diff --git a/compute/apiv1/accelerator_types_client.go b/compute/apiv1/accelerator_types_client.go
new file mode 100644
index 0000000..ebb96df
--- /dev/null
+++ b/compute/apiv1/accelerator_types_client.go
@@ -0,0 +1,341 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newAcceleratorTypesClientHook clientHook
+
+// AcceleratorTypesCallOptions contains the retry settings for each method of AcceleratorTypesClient.
+type AcceleratorTypesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Get            []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalAcceleratorTypesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalAcceleratorTypesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListAcceleratorTypesRequest, ...gax.CallOption) (*computepb.AcceleratorTypeAggregatedList, error)
+	Get(context.Context, *computepb.GetAcceleratorTypeRequest, ...gax.CallOption) (*computepb.AcceleratorType, error)
+	List(context.Context, *computepb.ListAcceleratorTypesRequest, ...gax.CallOption) (*computepb.AcceleratorTypeList, error)
+}
+
+// AcceleratorTypesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// Services
+//
+// The AcceleratorTypes API.
+type AcceleratorTypesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalAcceleratorTypesClient
+
+	// The call options for this service.
+	CallOptions *AcceleratorTypesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *AcceleratorTypesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *AcceleratorTypesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *AcceleratorTypesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of accelerator types.
+func (c *AcceleratorTypesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListAcceleratorTypesRequest, opts ...gax.CallOption) (*computepb.AcceleratorTypeAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Get returns the specified accelerator type.
+func (c *AcceleratorTypesClient) Get(ctx context.Context, req *computepb.GetAcceleratorTypeRequest, opts ...gax.CallOption) (*computepb.AcceleratorType, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of accelerator types that are available to the specified project.
+func (c *AcceleratorTypesClient) List(ctx context.Context, req *computepb.ListAcceleratorTypesRequest, opts ...gax.CallOption) (*computepb.AcceleratorTypeList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type acceleratorTypesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewAcceleratorTypesRESTClient creates a new accelerator types rest client.
+//
+// Services
+//
+// The AcceleratorTypes API.
+func NewAcceleratorTypesRESTClient(ctx context.Context, opts ...option.ClientOption) (*AcceleratorTypesClient, error) {
+	clientOpts := append(defaultAcceleratorTypesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &acceleratorTypesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &AcceleratorTypesClient{internalClient: c, CallOptions: &AcceleratorTypesCallOptions{}}, nil
+}
+
+func defaultAcceleratorTypesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *acceleratorTypesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *acceleratorTypesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *acceleratorTypesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of accelerator types.
+func (c *acceleratorTypesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListAcceleratorTypesRequest, opts ...gax.CallOption) (*computepb.AcceleratorTypeAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/acceleratorTypes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AcceleratorTypeAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified accelerator type.
+func (c *acceleratorTypesRESTClient) Get(ctx context.Context, req *computepb.GetAcceleratorTypeRequest, opts ...gax.CallOption) (*computepb.AcceleratorType, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/acceleratorTypes/%v", req.GetProject(), req.GetZone(), req.GetAcceleratorType())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AcceleratorType{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of accelerator types that are available to the specified project.
+func (c *acceleratorTypesRESTClient) List(ctx context.Context, req *computepb.ListAcceleratorTypesRequest, opts ...gax.CallOption) (*computepb.AcceleratorTypeList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/acceleratorTypes", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AcceleratorTypeList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/accelerator_types_client_example_test.go b/compute/apiv1/accelerator_types_client_example_test.go
new file mode 100644
index 0000000..ddb62c8
--- /dev/null
+++ b/compute/apiv1/accelerator_types_client_example_test.go
@@ -0,0 +1,93 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewAcceleratorTypesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewAcceleratorTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleAcceleratorTypesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewAcceleratorTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListAcceleratorTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAcceleratorTypesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewAcceleratorTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetAcceleratorTypeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAcceleratorTypesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewAcceleratorTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListAcceleratorTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/addresses_client.go b/compute/apiv1/addresses_client.go
new file mode 100644
index 0000000..0234364
--- /dev/null
+++ b/compute/apiv1/addresses_client.go
@@ -0,0 +1,452 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newAddressesClientHook clientHook
+
+// AddressesCallOptions contains the retry settings for each method of AddressesClient.
+type AddressesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalAddressesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalAddressesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListAddressesRequest, ...gax.CallOption) (*computepb.AddressAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteAddressRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetAddressRequest, ...gax.CallOption) (*computepb.Address, error)
+	Insert(context.Context, *computepb.InsertAddressRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListAddressesRequest, ...gax.CallOption) (*computepb.AddressList, error)
+}
+
+// AddressesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Addresses API.
+type AddressesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalAddressesClient
+
+	// The call options for this service.
+	CallOptions *AddressesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *AddressesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *AddressesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *AddressesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of addresses.
+func (c *AddressesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListAddressesRequest, opts ...gax.CallOption) (*computepb.AddressAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified address resource.
+func (c *AddressesClient) Delete(ctx context.Context, req *computepb.DeleteAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified address resource.
+func (c *AddressesClient) Get(ctx context.Context, req *computepb.GetAddressRequest, opts ...gax.CallOption) (*computepb.Address, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates an address resource in the specified project by using the data included in the request.
+func (c *AddressesClient) Insert(ctx context.Context, req *computepb.InsertAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of addresses contained within the specified region.
+func (c *AddressesClient) List(ctx context.Context, req *computepb.ListAddressesRequest, opts ...gax.CallOption) (*computepb.AddressList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type addressesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewAddressesRESTClient creates a new addresses rest client.
+//
+// The Addresses API.
+func NewAddressesRESTClient(ctx context.Context, opts ...option.ClientOption) (*AddressesClient, error) {
+	clientOpts := append(defaultAddressesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &addressesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &AddressesClient{internalClient: c, CallOptions: &AddressesCallOptions{}}, nil
+}
+
+func defaultAddressesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *addressesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *addressesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *addressesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of addresses.
+func (c *addressesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListAddressesRequest, opts ...gax.CallOption) (*computepb.AddressAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/addresses", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AddressAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified address resource.
+func (c *addressesRESTClient) Delete(ctx context.Context, req *computepb.DeleteAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/addresses/%v", req.GetProject(), req.GetRegion(), req.GetAddress())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified address resource.
+func (c *addressesRESTClient) Get(ctx context.Context, req *computepb.GetAddressRequest, opts ...gax.CallOption) (*computepb.Address, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/addresses/%v", req.GetProject(), req.GetRegion(), req.GetAddress())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Address{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an address resource in the specified project by using the data included in the request.
+func (c *addressesRESTClient) Insert(ctx context.Context, req *computepb.InsertAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAddressResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/addresses", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of addresses contained within the specified region.
+func (c *addressesRESTClient) List(ctx context.Context, req *computepb.ListAddressesRequest, opts ...gax.CallOption) (*computepb.AddressList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/addresses", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AddressList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/addresses_client_example_test.go b/compute/apiv1/addresses_client_example_test.go
new file mode 100644
index 0000000..8349df0
--- /dev/null
+++ b/compute/apiv1/addresses_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewAddressesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleAddressesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListAddressesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAddressesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteAddressRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAddressesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetAddressRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAddressesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertAddressRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAddressesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListAddressesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/autoscalers_client.go b/compute/apiv1/autoscalers_client.go
new file mode 100644
index 0000000..771438a
--- /dev/null
+++ b/compute/apiv1/autoscalers_client.go
@@ -0,0 +1,580 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newAutoscalersClientHook clientHook
+
+// AutoscalersCallOptions contains the retry settings for each method of AutoscalersClient.
+type AutoscalersCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+	Update         []gax.CallOption
+}
+
+// internalAutoscalersClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalAutoscalersClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListAutoscalersRequest, ...gax.CallOption) (*computepb.AutoscalerAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetAutoscalerRequest, ...gax.CallOption) (*computepb.Autoscaler, error)
+	Insert(context.Context, *computepb.InsertAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListAutoscalersRequest, ...gax.CallOption) (*computepb.AutoscalerList, error)
+	Patch(context.Context, *computepb.PatchAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// AutoscalersClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Autoscalers API.
+type AutoscalersClient struct {
+	// The internal transport-dependent client.
+	internalClient internalAutoscalersClient
+
+	// The call options for this service.
+	CallOptions *AutoscalersCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *AutoscalersClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *AutoscalersClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *AutoscalersClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of autoscalers.
+func (c *AutoscalersClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListAutoscalersRequest, opts ...gax.CallOption) (*computepb.AutoscalerAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified autoscaler.
+func (c *AutoscalersClient) Delete(ctx context.Context, req *computepb.DeleteAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified autoscaler resource. Gets a list of available autoscalers by making a list() request.
+func (c *AutoscalersClient) Get(ctx context.Context, req *computepb.GetAutoscalerRequest, opts ...gax.CallOption) (*computepb.Autoscaler, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates an autoscaler in the specified project using the data included in the request.
+func (c *AutoscalersClient) Insert(ctx context.Context, req *computepb.InsertAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of autoscalers contained within the specified zone.
+func (c *AutoscalersClient) List(ctx context.Context, req *computepb.ListAutoscalersRequest, opts ...gax.CallOption) (*computepb.AutoscalerList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates an autoscaler in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *AutoscalersClient) Patch(ctx context.Context, req *computepb.PatchAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates an autoscaler in the specified project using the data included in the request.
+func (c *AutoscalersClient) Update(ctx context.Context, req *computepb.UpdateAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type autoscalersRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewAutoscalersRESTClient creates a new autoscalers rest client.
+//
+// The Autoscalers API.
+func NewAutoscalersRESTClient(ctx context.Context, opts ...option.ClientOption) (*AutoscalersClient, error) {
+	clientOpts := append(defaultAutoscalersRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &autoscalersRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &AutoscalersClient{internalClient: c, CallOptions: &AutoscalersCallOptions{}}, nil
+}
+
+func defaultAutoscalersRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *autoscalersRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *autoscalersRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *autoscalersRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of autoscalers.
+func (c *autoscalersRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListAutoscalersRequest, opts ...gax.CallOption) (*computepb.AutoscalerAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/autoscalers", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AutoscalerAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified autoscaler.
+func (c *autoscalersRESTClient) Delete(ctx context.Context, req *computepb.DeleteAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/autoscalers/%v", req.GetProject(), req.GetZone(), req.GetAutoscaler())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified autoscaler resource. Gets a list of available autoscalers by making a list() request.
+func (c *autoscalersRESTClient) Get(ctx context.Context, req *computepb.GetAutoscalerRequest, opts ...gax.CallOption) (*computepb.Autoscaler, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/autoscalers/%v", req.GetProject(), req.GetZone(), req.GetAutoscaler())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Autoscaler{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an autoscaler in the specified project using the data included in the request.
+func (c *autoscalersRESTClient) Insert(ctx context.Context, req *computepb.InsertAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAutoscalerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/autoscalers", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of autoscalers contained within the specified zone.
+func (c *autoscalersRESTClient) List(ctx context.Context, req *computepb.ListAutoscalersRequest, opts ...gax.CallOption) (*computepb.AutoscalerList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/autoscalers", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AutoscalerList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates an autoscaler in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *autoscalersRESTClient) Patch(ctx context.Context, req *computepb.PatchAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAutoscalerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/autoscalers", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Autoscaler != nil {
+		params.Add("autoscaler", fmt.Sprintf("%v", req.GetAutoscaler()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates an autoscaler in the specified project using the data included in the request.
+func (c *autoscalersRESTClient) Update(ctx context.Context, req *computepb.UpdateAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAutoscalerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req != nil && req.Autoscaler != nil {
+		params.Add("autoscaler", fmt.Sprintf("%v", req.GetAutoscaler()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetZone() != "" {
+		params.Add("zone", fmt.Sprintf("%v", req.GetZone()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/autoscalers_client_example_test.go b/compute/apiv1/autoscalers_client_example_test.go
new file mode 100644
index 0000000..48fa08e
--- /dev/null
+++ b/compute/apiv1/autoscalers_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewAutoscalersRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleAutoscalersClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListAutoscalersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAutoscalersClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAutoscalersClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAutoscalersClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAutoscalersClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListAutoscalersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAutoscalersClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleAutoscalersClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/backend_buckets_client.go b/compute/apiv1/backend_buckets_client.go
new file mode 100644
index 0000000..89286c9
--- /dev/null
+++ b/compute/apiv1/backend_buckets_client.go
@@ -0,0 +1,620 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newBackendBucketsClientHook clientHook
+
+// BackendBucketsCallOptions contains the retry settings for each method of BackendBucketsClient.
+type BackendBucketsCallOptions struct {
+	AddSignedUrlKey    []gax.CallOption
+	Delete             []gax.CallOption
+	DeleteSignedUrlKey []gax.CallOption
+	Get                []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	Patch              []gax.CallOption
+	Update             []gax.CallOption
+}
+
+// internalBackendBucketsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalBackendBucketsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddSignedUrlKey(context.Context, *computepb.AddSignedUrlKeyBackendBucketRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteBackendBucketRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeleteSignedUrlKey(context.Context, *computepb.DeleteSignedUrlKeyBackendBucketRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetBackendBucketRequest, ...gax.CallOption) (*computepb.BackendBucket, error)
+	Insert(context.Context, *computepb.InsertBackendBucketRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListBackendBucketsRequest, ...gax.CallOption) (*computepb.BackendBucketList, error)
+	Patch(context.Context, *computepb.PatchBackendBucketRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateBackendBucketRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// BackendBucketsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The BackendBuckets API.
+type BackendBucketsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalBackendBucketsClient
+
+	// The call options for this service.
+	CallOptions *BackendBucketsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *BackendBucketsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *BackendBucketsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *BackendBucketsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddSignedUrlKey adds a key for validating requests with signed URLs for this backend bucket.
+func (c *BackendBucketsClient) AddSignedUrlKey(ctx context.Context, req *computepb.AddSignedUrlKeyBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddSignedUrlKey(ctx, req, opts...)
+}
+
+// Delete deletes the specified BackendBucket resource.
+func (c *BackendBucketsClient) Delete(ctx context.Context, req *computepb.DeleteBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DeleteSignedUrlKey deletes a key for validating requests with signed URLs for this backend bucket.
+func (c *BackendBucketsClient) DeleteSignedUrlKey(ctx context.Context, req *computepb.DeleteSignedUrlKeyBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeleteSignedUrlKey(ctx, req, opts...)
+}
+
+// Get returns the specified BackendBucket resource. Gets a list of available backend buckets by making a list() request.
+func (c *BackendBucketsClient) Get(ctx context.Context, req *computepb.GetBackendBucketRequest, opts ...gax.CallOption) (*computepb.BackendBucket, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a BackendBucket resource in the specified project using the data included in the request.
+func (c *BackendBucketsClient) Insert(ctx context.Context, req *computepb.InsertBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of BackendBucket resources available to the specified project.
+func (c *BackendBucketsClient) List(ctx context.Context, req *computepb.ListBackendBucketsRequest, opts ...gax.CallOption) (*computepb.BackendBucketList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified BackendBucket resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *BackendBucketsClient) Patch(ctx context.Context, req *computepb.PatchBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates the specified BackendBucket resource with the data included in the request.
+func (c *BackendBucketsClient) Update(ctx context.Context, req *computepb.UpdateBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type backendBucketsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewBackendBucketsRESTClient creates a new backend buckets rest client.
+//
+// The BackendBuckets API.
+func NewBackendBucketsRESTClient(ctx context.Context, opts ...option.ClientOption) (*BackendBucketsClient, error) {
+	clientOpts := append(defaultBackendBucketsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &backendBucketsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &BackendBucketsClient{internalClient: c, CallOptions: &BackendBucketsCallOptions{}}, nil
+}
+
+func defaultBackendBucketsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *backendBucketsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *backendBucketsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *backendBucketsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddSignedUrlKey adds a key for validating requests with signed URLs for this backend bucket.
+func (c *backendBucketsRESTClient) AddSignedUrlKey(ctx context.Context, req *computepb.AddSignedUrlKeyBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSignedUrlKeyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets/%v/addSignedUrlKey", req.GetProject(), req.GetBackendBucket())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified BackendBucket resource.
+func (c *backendBucketsRESTClient) Delete(ctx context.Context, req *computepb.DeleteBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets/%v", req.GetProject(), req.GetBackendBucket())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeleteSignedUrlKey deletes a key for validating requests with signed URLs for this backend bucket.
+func (c *backendBucketsRESTClient) DeleteSignedUrlKey(ctx context.Context, req *computepb.DeleteSignedUrlKeyBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets/%v/deleteSignedUrlKey", req.GetProject(), req.GetBackendBucket())
+
+	params := url.Values{}
+	if req.GetKeyName() != "" {
+		params.Add("keyName", fmt.Sprintf("%v", req.GetKeyName()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified BackendBucket resource. Gets a list of available backend buckets by making a list() request.
+func (c *backendBucketsRESTClient) Get(ctx context.Context, req *computepb.GetBackendBucketRequest, opts ...gax.CallOption) (*computepb.BackendBucket, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets/%v", req.GetProject(), req.GetBackendBucket())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendBucket{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a BackendBucket resource in the specified project using the data included in the request.
+func (c *backendBucketsRESTClient) Insert(ctx context.Context, req *computepb.InsertBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendBucketResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of BackendBucket resources available to the specified project.
+func (c *backendBucketsRESTClient) List(ctx context.Context, req *computepb.ListBackendBucketsRequest, opts ...gax.CallOption) (*computepb.BackendBucketList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendBucketList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified BackendBucket resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *backendBucketsRESTClient) Patch(ctx context.Context, req *computepb.PatchBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendBucketResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendBuckets/%v", req.GetProject(), req.GetBackendBucket())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified BackendBucket resource with the data included in the request.
+func (c *backendBucketsRESTClient) Update(ctx context.Context, req *computepb.UpdateBackendBucketRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendBucketResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetBackendBucket() != "" {
+		params.Add("backendBucket", fmt.Sprintf("%v", req.GetBackendBucket()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/backend_buckets_client_example_test.go b/compute/apiv1/backend_buckets_client_example_test.go
new file mode 100644
index 0000000..1a7f352
--- /dev/null
+++ b/compute/apiv1/backend_buckets_client_example_test.go
@@ -0,0 +1,188 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewBackendBucketsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleBackendBucketsClient_AddSignedUrlKey() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddSignedUrlKeyBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddSignedUrlKey(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_DeleteSignedUrlKey() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSignedUrlKeyBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeleteSignedUrlKey(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListBackendBucketsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendBucketsClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewBackendBucketsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateBackendBucketRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/backend_services_client.go b/compute/apiv1/backend_services_client.go
new file mode 100644
index 0000000..b6dc5e5
--- /dev/null
+++ b/compute/apiv1/backend_services_client.go
@@ -0,0 +1,809 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newBackendServicesClientHook clientHook
+
+// BackendServicesCallOptions contains the retry settings for each method of BackendServicesClient.
+type BackendServicesCallOptions struct {
+	AddSignedUrlKey    []gax.CallOption
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	DeleteSignedUrlKey []gax.CallOption
+	Get                []gax.CallOption
+	GetHealth          []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	Patch              []gax.CallOption
+	SetSecurityPolicy  []gax.CallOption
+	Update             []gax.CallOption
+}
+
+// internalBackendServicesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalBackendServicesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddSignedUrlKey(context.Context, *computepb.AddSignedUrlKeyBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListBackendServicesRequest, ...gax.CallOption) (*computepb.BackendServiceAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeleteSignedUrlKey(context.Context, *computepb.DeleteSignedUrlKeyBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetBackendServiceRequest, ...gax.CallOption) (*computepb.BackendService, error)
+	GetHealth(context.Context, *computepb.GetHealthBackendServiceRequest, ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error)
+	Insert(context.Context, *computepb.InsertBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListBackendServicesRequest, ...gax.CallOption) (*computepb.BackendServiceList, error)
+	Patch(context.Context, *computepb.PatchBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetSecurityPolicy(context.Context, *computepb.SetSecurityPolicyBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// BackendServicesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The BackendServices API.
+type BackendServicesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalBackendServicesClient
+
+	// The call options for this service.
+	CallOptions *BackendServicesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *BackendServicesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *BackendServicesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *BackendServicesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddSignedUrlKey adds a key for validating requests with signed URLs for this backend service.
+func (c *BackendServicesClient) AddSignedUrlKey(ctx context.Context, req *computepb.AddSignedUrlKeyBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddSignedUrlKey(ctx, req, opts...)
+}
+
+// AggregatedList retrieves the list of all BackendService resources, regional and global, available to the specified project.
+func (c *BackendServicesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListBackendServicesRequest, opts ...gax.CallOption) (*computepb.BackendServiceAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified BackendService resource.
+func (c *BackendServicesClient) Delete(ctx context.Context, req *computepb.DeleteBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DeleteSignedUrlKey deletes a key for validating requests with signed URLs for this backend service.
+func (c *BackendServicesClient) DeleteSignedUrlKey(ctx context.Context, req *computepb.DeleteSignedUrlKeyBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeleteSignedUrlKey(ctx, req, opts...)
+}
+
+// Get returns the specified BackendService resource. Gets a list of available backend services.
+func (c *BackendServicesClient) Get(ctx context.Context, req *computepb.GetBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendService, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetHealth gets the most recent health check results for this BackendService.
+//
+// Example request body:
+//
+// { “group”: “/zones/us-east1-b/instanceGroups/lb-backend-example” }
+func (c *BackendServicesClient) GetHealth(ctx context.Context, req *computepb.GetHealthBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error) {
+	return c.internalClient.GetHealth(ctx, req, opts...)
+}
+
+// Insert creates a BackendService resource in the specified project using the data included in the request. For more information, see  Backend services overview.
+func (c *BackendServicesClient) Insert(ctx context.Context, req *computepb.InsertBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of BackendService resources available to the specified project.
+func (c *BackendServicesClient) List(ctx context.Context, req *computepb.ListBackendServicesRequest, opts ...gax.CallOption) (*computepb.BackendServiceList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified BackendService resource with the data included in the request. For more information, see  Backend services overview. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *BackendServicesClient) Patch(ctx context.Context, req *computepb.PatchBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetSecurityPolicy sets the Google Cloud Armor security policy for the specified backend service. For more information, see Google Cloud Armor Overview
+func (c *BackendServicesClient) SetSecurityPolicy(ctx context.Context, req *computepb.SetSecurityPolicyBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetSecurityPolicy(ctx, req, opts...)
+}
+
+// Update updates the specified BackendService resource with the data included in the request. For more information, see Backend services overview.
+func (c *BackendServicesClient) Update(ctx context.Context, req *computepb.UpdateBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type backendServicesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewBackendServicesRESTClient creates a new backend services rest client.
+//
+// The BackendServices API.
+func NewBackendServicesRESTClient(ctx context.Context, opts ...option.ClientOption) (*BackendServicesClient, error) {
+	clientOpts := append(defaultBackendServicesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &backendServicesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &BackendServicesClient{internalClient: c, CallOptions: &BackendServicesCallOptions{}}, nil
+}
+
+func defaultBackendServicesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *backendServicesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *backendServicesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *backendServicesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddSignedUrlKey adds a key for validating requests with signed URLs for this backend service.
+func (c *backendServicesRESTClient) AddSignedUrlKey(ctx context.Context, req *computepb.AddSignedUrlKeyBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSignedUrlKeyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v/addSignedUrlKey", req.GetProject(), req.GetBackendService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves the list of all BackendService resources, regional and global, available to the specified project.
+func (c *backendServicesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListBackendServicesRequest, opts ...gax.CallOption) (*computepb.BackendServiceAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/backendServices", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendServiceAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified BackendService resource.
+func (c *backendServicesRESTClient) Delete(ctx context.Context, req *computepb.DeleteBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v", req.GetProject(), req.GetBackendService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeleteSignedUrlKey deletes a key for validating requests with signed URLs for this backend service.
+func (c *backendServicesRESTClient) DeleteSignedUrlKey(ctx context.Context, req *computepb.DeleteSignedUrlKeyBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v/deleteSignedUrlKey", req.GetProject(), req.GetBackendService())
+
+	params := url.Values{}
+	if req.GetKeyName() != "" {
+		params.Add("keyName", fmt.Sprintf("%v", req.GetKeyName()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified BackendService resource. Gets a list of available backend services.
+func (c *backendServicesRESTClient) Get(ctx context.Context, req *computepb.GetBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendService, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v", req.GetProject(), req.GetBackendService())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendService{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetHealth gets the most recent health check results for this BackendService.
+//
+// Example request body:
+//
+// { “group”: “/zones/us-east1-b/instanceGroups/lb-backend-example” }
+func (c *backendServicesRESTClient) GetHealth(ctx context.Context, req *computepb.GetHealthBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetResourceGroupReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v/getHealth", req.GetProject(), req.GetBackendService())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendServiceGroupHealth{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a BackendService resource in the specified project using the data included in the request. For more information, see  Backend services overview.
+func (c *backendServicesRESTClient) Insert(ctx context.Context, req *computepb.InsertBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of BackendService resources available to the specified project.
+func (c *backendServicesRESTClient) List(ctx context.Context, req *computepb.ListBackendServicesRequest, opts ...gax.CallOption) (*computepb.BackendServiceList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendServiceList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified BackendService resource with the data included in the request. For more information, see  Backend services overview. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *backendServicesRESTClient) Patch(ctx context.Context, req *computepb.PatchBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v", req.GetProject(), req.GetBackendService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetSecurityPolicy sets the Google Cloud Armor security policy for the specified backend service. For more information, see Google Cloud Armor Overview
+func (c *backendServicesRESTClient) SetSecurityPolicy(ctx context.Context, req *computepb.SetSecurityPolicyBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSecurityPolicyReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/backendServices/%v/setSecurityPolicy", req.GetProject(), req.GetBackendService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified BackendService resource with the data included in the request. For more information, see Backend services overview.
+func (c *backendServicesRESTClient) Update(ctx context.Context, req *computepb.UpdateBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetBackendService() != "" {
+		params.Add("backendService", fmt.Sprintf("%v", req.GetBackendService()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/backend_services_client_example_test.go b/compute/apiv1/backend_services_client_example_test.go
new file mode 100644
index 0000000..6bdbd1e
--- /dev/null
+++ b/compute/apiv1/backend_services_client_example_test.go
@@ -0,0 +1,245 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewBackendServicesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleBackendServicesClient_AddSignedUrlKey() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddSignedUrlKeyBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddSignedUrlKey(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListBackendServicesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_DeleteSignedUrlKey() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSignedUrlKeyBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeleteSignedUrlKey(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_GetHealth() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetHealthBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetHealth(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListBackendServicesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_SetSecurityPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSecurityPolicyBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetSecurityPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleBackendServicesClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/disk_types_client.go b/compute/apiv1/disk_types_client.go
new file mode 100644
index 0000000..aeb5487
--- /dev/null
+++ b/compute/apiv1/disk_types_client.go
@@ -0,0 +1,337 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newDiskTypesClientHook clientHook
+
+// DiskTypesCallOptions contains the retry settings for each method of DiskTypesClient.
+type DiskTypesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Get            []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalDiskTypesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalDiskTypesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListDiskTypesRequest, ...gax.CallOption) (*computepb.DiskTypeAggregatedList, error)
+	Get(context.Context, *computepb.GetDiskTypeRequest, ...gax.CallOption) (*computepb.DiskType, error)
+	List(context.Context, *computepb.ListDiskTypesRequest, ...gax.CallOption) (*computepb.DiskTypeList, error)
+}
+
+// DiskTypesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The DiskTypes API.
+type DiskTypesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalDiskTypesClient
+
+	// The call options for this service.
+	CallOptions *DiskTypesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *DiskTypesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *DiskTypesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *DiskTypesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of disk types.
+func (c *DiskTypesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListDiskTypesRequest, opts ...gax.CallOption) (*computepb.DiskTypeAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Get returns the specified disk type. Gets a list of available disk types by making a list() request.
+func (c *DiskTypesClient) Get(ctx context.Context, req *computepb.GetDiskTypeRequest, opts ...gax.CallOption) (*computepb.DiskType, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of disk types available to the specified project.
+func (c *DiskTypesClient) List(ctx context.Context, req *computepb.ListDiskTypesRequest, opts ...gax.CallOption) (*computepb.DiskTypeList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type diskTypesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewDiskTypesRESTClient creates a new disk types rest client.
+//
+// The DiskTypes API.
+func NewDiskTypesRESTClient(ctx context.Context, opts ...option.ClientOption) (*DiskTypesClient, error) {
+	clientOpts := append(defaultDiskTypesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &diskTypesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &DiskTypesClient{internalClient: c, CallOptions: &DiskTypesCallOptions{}}, nil
+}
+
+func defaultDiskTypesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *diskTypesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *diskTypesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *diskTypesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of disk types.
+func (c *diskTypesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListDiskTypesRequest, opts ...gax.CallOption) (*computepb.DiskTypeAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/diskTypes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskTypeAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified disk type. Gets a list of available disk types by making a list() request.
+func (c *diskTypesRESTClient) Get(ctx context.Context, req *computepb.GetDiskTypeRequest, opts ...gax.CallOption) (*computepb.DiskType, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/diskTypes/%v", req.GetProject(), req.GetZone(), req.GetDiskType())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskType{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of disk types available to the specified project.
+func (c *diskTypesRESTClient) List(ctx context.Context, req *computepb.ListDiskTypesRequest, opts ...gax.CallOption) (*computepb.DiskTypeList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/diskTypes", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskTypeList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/disk_types_client_example_test.go b/compute/apiv1/disk_types_client_example_test.go
new file mode 100644
index 0000000..db2c18b
--- /dev/null
+++ b/compute/apiv1/disk_types_client_example_test.go
@@ -0,0 +1,93 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewDiskTypesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleDiskTypesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListDiskTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDiskTypesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetDiskTypeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDiskTypesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListDiskTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/disks_client.go b/compute/apiv1/disks_client.go
new file mode 100644
index 0000000..60e3f5e
--- /dev/null
+++ b/compute/apiv1/disks_client.go
@@ -0,0 +1,907 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newDisksClientHook clientHook
+
+// DisksCallOptions contains the retry settings for each method of DisksClient.
+type DisksCallOptions struct {
+	AddResourcePolicies    []gax.CallOption
+	AggregatedList         []gax.CallOption
+	CreateSnapshot         []gax.CallOption
+	Delete                 []gax.CallOption
+	Get                    []gax.CallOption
+	GetIamPolicy           []gax.CallOption
+	Insert                 []gax.CallOption
+	List                   []gax.CallOption
+	RemoveResourcePolicies []gax.CallOption
+	Resize                 []gax.CallOption
+	SetIamPolicy           []gax.CallOption
+	SetLabels              []gax.CallOption
+	TestIamPermissions     []gax.CallOption
+}
+
+// internalDisksClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalDisksClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddResourcePolicies(context.Context, *computepb.AddResourcePoliciesDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListDisksRequest, ...gax.CallOption) (*computepb.DiskAggregatedList, error)
+	CreateSnapshot(context.Context, *computepb.CreateSnapshotDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetDiskRequest, ...gax.CallOption) (*computepb.Disk, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyDiskRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListDisksRequest, ...gax.CallOption) (*computepb.DiskList, error)
+	RemoveResourcePolicies(context.Context, *computepb.RemoveResourcePoliciesDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Resize(context.Context, *computepb.ResizeDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyDiskRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetLabels(context.Context, *computepb.SetLabelsDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsDiskRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// DisksClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Disks API.
+type DisksClient struct {
+	// The internal transport-dependent client.
+	internalClient internalDisksClient
+
+	// The call options for this service.
+	CallOptions *DisksCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *DisksClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *DisksClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *DisksClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddResourcePolicies adds existing resource policies to a disk. You can only add one policy which will be applied to this disk for scheduling snapshot creation.
+func (c *DisksClient) AddResourcePolicies(ctx context.Context, req *computepb.AddResourcePoliciesDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddResourcePolicies(ctx, req, opts...)
+}
+
+// AggregatedList retrieves an aggregated list of persistent disks.
+func (c *DisksClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListDisksRequest, opts ...gax.CallOption) (*computepb.DiskAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// CreateSnapshot creates a snapshot of a specified persistent disk.
+func (c *DisksClient) CreateSnapshot(ctx context.Context, req *computepb.CreateSnapshotDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.CreateSnapshot(ctx, req, opts...)
+}
+
+// Delete deletes the specified persistent disk. Deleting a disk removes its data permanently and is irreversible. However, deleting a disk does not delete any snapshots previously made from the disk. You must separately delete snapshots.
+func (c *DisksClient) Delete(ctx context.Context, req *computepb.DeleteDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns a specified persistent disk. Gets a list of available persistent disks by making a list() request.
+func (c *DisksClient) Get(ctx context.Context, req *computepb.GetDiskRequest, opts ...gax.CallOption) (*computepb.Disk, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *DisksClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a persistent disk in the specified project using the data in the request. You can create a disk from a source (sourceImage, sourceSnapshot, or sourceDisk) or create an empty 500 GB data disk by omitting all properties. You can also create a disk that is larger than the default size by specifying the sizeGb property.
+func (c *DisksClient) Insert(ctx context.Context, req *computepb.InsertDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of persistent disks contained within the specified zone.
+func (c *DisksClient) List(ctx context.Context, req *computepb.ListDisksRequest, opts ...gax.CallOption) (*computepb.DiskList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// RemoveResourcePolicies removes resource policies from a disk.
+func (c *DisksClient) RemoveResourcePolicies(ctx context.Context, req *computepb.RemoveResourcePoliciesDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveResourcePolicies(ctx, req, opts...)
+}
+
+// Resize resizes the specified persistent disk. You can only increase the size of the disk.
+func (c *DisksClient) Resize(ctx context.Context, req *computepb.ResizeDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Resize(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *DisksClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on a disk. To learn more about labels, read the Labeling Resources documentation.
+func (c *DisksClient) SetLabels(ctx context.Context, req *computepb.SetLabelsDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *DisksClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsDiskRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type disksRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewDisksRESTClient creates a new disks rest client.
+//
+// The Disks API.
+func NewDisksRESTClient(ctx context.Context, opts ...option.ClientOption) (*DisksClient, error) {
+	clientOpts := append(defaultDisksRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &disksRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &DisksClient{internalClient: c, CallOptions: &DisksCallOptions{}}, nil
+}
+
+func defaultDisksRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *disksRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *disksRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *disksRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddResourcePolicies adds existing resource policies to a disk. You can only add one policy which will be applied to this disk for scheduling snapshot creation.
+func (c *disksRESTClient) AddResourcePolicies(ctx context.Context, req *computepb.AddResourcePoliciesDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDisksAddResourcePoliciesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/addResourcePolicies", req.GetProject(), req.GetZone(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves an aggregated list of persistent disks.
+func (c *disksRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListDisksRequest, opts ...gax.CallOption) (*computepb.DiskAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/disks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// CreateSnapshot creates a snapshot of a specified persistent disk.
+func (c *disksRESTClient) CreateSnapshot(ctx context.Context, req *computepb.CreateSnapshotDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSnapshotResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/createSnapshot", req.GetProject(), req.GetZone(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.GuestFlush != nil {
+		params.Add("guestFlush", fmt.Sprintf("%v", req.GetGuestFlush()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified persistent disk. Deleting a disk removes its data permanently and is irreversible. However, deleting a disk does not delete any snapshots previously made from the disk. You must separately delete snapshots.
+func (c *disksRESTClient) Delete(ctx context.Context, req *computepb.DeleteDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v", req.GetProject(), req.GetZone(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns a specified persistent disk. Gets a list of available persistent disks by making a list() request.
+func (c *disksRESTClient) Get(ctx context.Context, req *computepb.GetDiskRequest, opts ...gax.CallOption) (*computepb.Disk, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v", req.GetProject(), req.GetZone(), req.GetDisk())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Disk{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *disksRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/getIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a persistent disk in the specified project using the data in the request. You can create a disk from a source (sourceImage, sourceSnapshot, or sourceDisk) or create an empty 500 GB data disk by omitting all properties. You can also create a disk that is larger than the default size by specifying the sizeGb property.
+func (c *disksRESTClient) Insert(ctx context.Context, req *computepb.InsertDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDiskResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req != nil && req.SourceImage != nil {
+		params.Add("sourceImage", fmt.Sprintf("%v", req.GetSourceImage()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of persistent disks contained within the specified zone.
+func (c *disksRESTClient) List(ctx context.Context, req *computepb.ListDisksRequest, opts ...gax.CallOption) (*computepb.DiskList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveResourcePolicies removes resource policies from a disk.
+func (c *disksRESTClient) RemoveResourcePolicies(ctx context.Context, req *computepb.RemoveResourcePoliciesDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDisksRemoveResourcePoliciesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/removeResourcePolicies", req.GetProject(), req.GetZone(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Resize resizes the specified persistent disk. You can only increase the size of the disk.
+func (c *disksRESTClient) Resize(ctx context.Context, req *computepb.ResizeDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDisksResizeRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/resize", req.GetProject(), req.GetZone(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *disksRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetZoneSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/setIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on a disk. To learn more about labels, read the Labeling Resources documentation.
+func (c *disksRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetZoneSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/setLabels", req.GetProject(), req.GetZone(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *disksRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsDiskRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/disks/%v/testIamPermissions", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/disks_client_example_test.go b/compute/apiv1/disks_client_example_test.go
new file mode 100644
index 0000000..cbdcd91
--- /dev/null
+++ b/compute/apiv1/disks_client_example_test.go
@@ -0,0 +1,283 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewDisksRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleDisksClient_AddResourcePolicies() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddResourcePoliciesDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddResourcePolicies(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListDisksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_CreateSnapshot() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.CreateSnapshotDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.CreateSnapshot(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListDisksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_RemoveResourcePolicies() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveResourcePoliciesDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveResourcePolicies(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_Resize() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ResizeDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Resize(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleDisksClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/doc.go b/compute/apiv1/doc.go
new file mode 100644
index 0000000..4b6efeb
--- /dev/null
+++ b/compute/apiv1/doc.go
@@ -0,0 +1,118 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+// Package compute is an auto-generated package for the
+// Google Compute Engine API.
+//
+//   NOTE: This package is in alpha. It is not stable, and is likely to change.
+//
+// Use of Context
+//
+// The ctx passed to NewClient is used for authentication requests and
+// for creating the underlying connection, but is not used for subsequent calls.
+// Individual methods on the client use the ctx given to them.
+//
+// To close the open connection, use the Close() method.
+//
+// For information about setting deadlines, reusing contexts, and more
+// please visit https://pkg.go.dev/cloud.google.com/go.
+package compute // import "cloud.google.com/go/compute/apiv1"
+
+import (
+	"context"
+	"os"
+	"runtime"
+	"strconv"
+	"strings"
+	"unicode"
+
+	"google.golang.org/api/option"
+	"google.golang.org/grpc/metadata"
+)
+
+// For more information on implementing a client constructor hook, see
+// https://github.com/googleapis/google-cloud-go/wiki/Customizing-constructors.
+type clientHookParams struct{}
+type clientHook func(context.Context, clientHookParams) ([]option.ClientOption, error)
+
+const versionClient = "20210701"
+
+func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
+	out, _ := metadata.FromOutgoingContext(ctx)
+	out = out.Copy()
+	for _, md := range mds {
+		for k, v := range md {
+			out[k] = append(out[k], v...)
+		}
+	}
+	return metadata.NewOutgoingContext(ctx, out)
+}
+
+func checkDisableDeadlines() (bool, error) {
+	raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE")
+	if !ok {
+		return false, nil
+	}
+
+	b, err := strconv.ParseBool(raw)
+	return b, err
+}
+
+// DefaultAuthScopes reports the default set of authentication scopes to use with this package.
+func DefaultAuthScopes() []string {
+	return []string{
+		"https://www.googleapis.com/auth/cloud-platform",
+		"https://www.googleapis.com/auth/compute",
+		"https://www.googleapis.com/auth/compute.readonly",
+	}
+}
+
+// versionGo returns the Go runtime version. The returned string
+// has no whitespace, suitable for reporting in header.
+func versionGo() string {
+	const develPrefix = "devel +"
+
+	s := runtime.Version()
+	if strings.HasPrefix(s, develPrefix) {
+		s = s[len(develPrefix):]
+		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+			s = s[:p]
+		}
+		return s
+	}
+
+	notSemverRune := func(r rune) bool {
+		return !strings.ContainsRune("0123456789.", r)
+	}
+
+	if strings.HasPrefix(s, "go1") {
+		s = s[2:]
+		var prerelease string
+		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
+			s, prerelease = s[:p], s[p:]
+		}
+		if strings.HasSuffix(s, ".") {
+			s += "0"
+		} else if strings.Count(s, ".") < 2 {
+			s += ".0"
+		}
+		if prerelease != "" {
+			s += "-" + prerelease
+		}
+		return s
+	}
+	return "UNKNOWN"
+}
diff --git a/compute/apiv1/external_vpn_gateways_client.go b/compute/apiv1/external_vpn_gateways_client.go
new file mode 100644
index 0000000..00311af
--- /dev/null
+++ b/compute/apiv1/external_vpn_gateways_client.go
@@ -0,0 +1,482 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newExternalVpnGatewaysClientHook clientHook
+
+// ExternalVpnGatewaysCallOptions contains the retry settings for each method of ExternalVpnGatewaysClient.
+type ExternalVpnGatewaysCallOptions struct {
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetLabels          []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalExternalVpnGatewaysClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalExternalVpnGatewaysClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteExternalVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetExternalVpnGatewayRequest, ...gax.CallOption) (*computepb.ExternalVpnGateway, error)
+	Insert(context.Context, *computepb.InsertExternalVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListExternalVpnGatewaysRequest, ...gax.CallOption) (*computepb.ExternalVpnGatewayList, error)
+	SetLabels(context.Context, *computepb.SetLabelsExternalVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsExternalVpnGatewayRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// ExternalVpnGatewaysClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The ExternalVpnGateways API.
+type ExternalVpnGatewaysClient struct {
+	// The internal transport-dependent client.
+	internalClient internalExternalVpnGatewaysClient
+
+	// The call options for this service.
+	CallOptions *ExternalVpnGatewaysCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ExternalVpnGatewaysClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ExternalVpnGatewaysClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ExternalVpnGatewaysClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified externalVpnGateway.
+func (c *ExternalVpnGatewaysClient) Delete(ctx context.Context, req *computepb.DeleteExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified externalVpnGateway. Get a list of available externalVpnGateways by making a list() request.
+func (c *ExternalVpnGatewaysClient) Get(ctx context.Context, req *computepb.GetExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.ExternalVpnGateway, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a ExternalVpnGateway in the specified project using the data included in the request.
+func (c *ExternalVpnGatewaysClient) Insert(ctx context.Context, req *computepb.InsertExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of ExternalVpnGateway available to the specified project.
+func (c *ExternalVpnGatewaysClient) List(ctx context.Context, req *computepb.ListExternalVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.ExternalVpnGatewayList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on an ExternalVpnGateway. To learn more about labels, read the Labeling Resources documentation.
+func (c *ExternalVpnGatewaysClient) SetLabels(ctx context.Context, req *computepb.SetLabelsExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *ExternalVpnGatewaysClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type externalVpnGatewaysRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewExternalVpnGatewaysRESTClient creates a new external vpn gateways rest client.
+//
+// The ExternalVpnGateways API.
+func NewExternalVpnGatewaysRESTClient(ctx context.Context, opts ...option.ClientOption) (*ExternalVpnGatewaysClient, error) {
+	clientOpts := append(defaultExternalVpnGatewaysRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &externalVpnGatewaysRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ExternalVpnGatewaysClient{internalClient: c, CallOptions: &ExternalVpnGatewaysCallOptions{}}, nil
+}
+
+func defaultExternalVpnGatewaysRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *externalVpnGatewaysRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *externalVpnGatewaysRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *externalVpnGatewaysRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified externalVpnGateway.
+func (c *externalVpnGatewaysRESTClient) Delete(ctx context.Context, req *computepb.DeleteExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/externalVpnGateways/%v", req.GetProject(), req.GetExternalVpnGateway())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified externalVpnGateway. Get a list of available externalVpnGateways by making a list() request.
+func (c *externalVpnGatewaysRESTClient) Get(ctx context.Context, req *computepb.GetExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.ExternalVpnGateway, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/externalVpnGateways/%v", req.GetProject(), req.GetExternalVpnGateway())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ExternalVpnGateway{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a ExternalVpnGateway in the specified project using the data included in the request.
+func (c *externalVpnGatewaysRESTClient) Insert(ctx context.Context, req *computepb.InsertExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetExternalVpnGatewayResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/externalVpnGateways", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of ExternalVpnGateway available to the specified project.
+func (c *externalVpnGatewaysRESTClient) List(ctx context.Context, req *computepb.ListExternalVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.ExternalVpnGatewayList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/externalVpnGateways", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ExternalVpnGatewayList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on an ExternalVpnGateway. To learn more about labels, read the Labeling Resources documentation.
+func (c *externalVpnGatewaysRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/externalVpnGateways/%v/setLabels", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *externalVpnGatewaysRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsExternalVpnGatewayRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/externalVpnGateways/%v/testIamPermissions", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/external_vpn_gateways_client_example_test.go b/compute/apiv1/external_vpn_gateways_client_example_test.go
new file mode 100644
index 0000000..820c2c0
--- /dev/null
+++ b/compute/apiv1/external_vpn_gateways_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewExternalVpnGatewaysRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleExternalVpnGatewaysClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteExternalVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleExternalVpnGatewaysClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetExternalVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleExternalVpnGatewaysClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertExternalVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleExternalVpnGatewaysClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListExternalVpnGatewaysRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleExternalVpnGatewaysClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsExternalVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleExternalVpnGatewaysClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsExternalVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/firewall_policies_client.go b/compute/apiv1/firewall_policies_client.go
new file mode 100644
index 0000000..4b224a9
--- /dev/null
+++ b/compute/apiv1/firewall_policies_client.go
@@ -0,0 +1,1194 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newFirewallPoliciesClientHook clientHook
+
+// FirewallPoliciesCallOptions contains the retry settings for each method of FirewallPoliciesClient.
+type FirewallPoliciesCallOptions struct {
+	AddAssociation     []gax.CallOption
+	AddRule            []gax.CallOption
+	CloneRules         []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetAssociation     []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	GetRule            []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	ListAssociations   []gax.CallOption
+	Move               []gax.CallOption
+	Patch              []gax.CallOption
+	PatchRule          []gax.CallOption
+	RemoveAssociation  []gax.CallOption
+	RemoveRule         []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalFirewallPoliciesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalFirewallPoliciesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddAssociation(context.Context, *computepb.AddAssociationFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AddRule(context.Context, *computepb.AddRuleFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	CloneRules(context.Context, *computepb.CloneRulesFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetFirewallPolicyRequest, ...gax.CallOption) (*computepb.FirewallPolicy, error)
+	GetAssociation(context.Context, *computepb.GetAssociationFirewallPolicyRequest, ...gax.CallOption) (*computepb.FirewallPolicyAssociation, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyFirewallPolicyRequest, ...gax.CallOption) (*computepb.Policy, error)
+	GetRule(context.Context, *computepb.GetRuleFirewallPolicyRequest, ...gax.CallOption) (*computepb.FirewallPolicyRule, error)
+	Insert(context.Context, *computepb.InsertFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListFirewallPoliciesRequest, ...gax.CallOption) (*computepb.FirewallPolicyList, error)
+	ListAssociations(context.Context, *computepb.ListAssociationsFirewallPolicyRequest, ...gax.CallOption) (*computepb.FirewallPoliciesListAssociationsResponse, error)
+	Move(context.Context, *computepb.MoveFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Patch(context.Context, *computepb.PatchFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	PatchRule(context.Context, *computepb.PatchRuleFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RemoveAssociation(context.Context, *computepb.RemoveAssociationFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RemoveRule(context.Context, *computepb.RemoveRuleFirewallPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyFirewallPolicyRequest, ...gax.CallOption) (*computepb.Policy, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsFirewallPolicyRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// FirewallPoliciesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The FirewallPolicies API.
+type FirewallPoliciesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalFirewallPoliciesClient
+
+	// The call options for this service.
+	CallOptions *FirewallPoliciesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *FirewallPoliciesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *FirewallPoliciesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *FirewallPoliciesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddAssociation inserts an association for the specified firewall policy.
+func (c *FirewallPoliciesClient) AddAssociation(ctx context.Context, req *computepb.AddAssociationFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddAssociation(ctx, req, opts...)
+}
+
+// AddRule inserts a rule into a firewall policy.
+func (c *FirewallPoliciesClient) AddRule(ctx context.Context, req *computepb.AddRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddRule(ctx, req, opts...)
+}
+
+// CloneRules copies rules to the specified firewall policy.
+func (c *FirewallPoliciesClient) CloneRules(ctx context.Context, req *computepb.CloneRulesFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.CloneRules(ctx, req, opts...)
+}
+
+// Delete deletes the specified policy.
+func (c *FirewallPoliciesClient) Delete(ctx context.Context, req *computepb.DeleteFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified firewall policy.
+func (c *FirewallPoliciesClient) Get(ctx context.Context, req *computepb.GetFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPolicy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetAssociation gets an association with the specified name.
+func (c *FirewallPoliciesClient) GetAssociation(ctx context.Context, req *computepb.GetAssociationFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPolicyAssociation, error) {
+	return c.internalClient.GetAssociation(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *FirewallPoliciesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// GetRule gets a rule of the specified priority.
+func (c *FirewallPoliciesClient) GetRule(ctx context.Context, req *computepb.GetRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPolicyRule, error) {
+	return c.internalClient.GetRule(ctx, req, opts...)
+}
+
+// Insert creates a new policy in the specified project using the data included in the request.
+func (c *FirewallPoliciesClient) Insert(ctx context.Context, req *computepb.InsertFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists all the policies that have been configured for the specified project.
+func (c *FirewallPoliciesClient) List(ctx context.Context, req *computepb.ListFirewallPoliciesRequest, opts ...gax.CallOption) (*computepb.FirewallPolicyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListAssociations lists associations of a specified target, i.e., organization or folder.
+func (c *FirewallPoliciesClient) ListAssociations(ctx context.Context, req *computepb.ListAssociationsFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPoliciesListAssociationsResponse, error) {
+	return c.internalClient.ListAssociations(ctx, req, opts...)
+}
+
+// Move moves the specified firewall policy.
+func (c *FirewallPoliciesClient) Move(ctx context.Context, req *computepb.MoveFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Move(ctx, req, opts...)
+}
+
+// Patch patches the specified policy with the data included in the request.
+func (c *FirewallPoliciesClient) Patch(ctx context.Context, req *computepb.PatchFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// PatchRule patches a rule of the specified priority.
+func (c *FirewallPoliciesClient) PatchRule(ctx context.Context, req *computepb.PatchRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.PatchRule(ctx, req, opts...)
+}
+
+// RemoveAssociation removes an association for the specified firewall policy.
+func (c *FirewallPoliciesClient) RemoveAssociation(ctx context.Context, req *computepb.RemoveAssociationFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveAssociation(ctx, req, opts...)
+}
+
+// RemoveRule deletes a rule of the specified priority.
+func (c *FirewallPoliciesClient) RemoveRule(ctx context.Context, req *computepb.RemoveRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveRule(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *FirewallPoliciesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *FirewallPoliciesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type firewallPoliciesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewFirewallPoliciesRESTClient creates a new firewall policies rest client.
+//
+// The FirewallPolicies API.
+func NewFirewallPoliciesRESTClient(ctx context.Context, opts ...option.ClientOption) (*FirewallPoliciesClient, error) {
+	clientOpts := append(defaultFirewallPoliciesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &firewallPoliciesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &FirewallPoliciesClient{internalClient: c, CallOptions: &FirewallPoliciesCallOptions{}}, nil
+}
+
+func defaultFirewallPoliciesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *firewallPoliciesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *firewallPoliciesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *firewallPoliciesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddAssociation inserts an association for the specified firewall policy.
+func (c *firewallPoliciesRESTClient) AddAssociation(ctx context.Context, req *computepb.AddAssociationFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallPolicyAssociationResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/addAssociation", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.ReplaceExistingAssociation != nil {
+		params.Add("replaceExistingAssociation", fmt.Sprintf("%v", req.GetReplaceExistingAssociation()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AddRule inserts a rule into a firewall policy.
+func (c *firewallPoliciesRESTClient) AddRule(ctx context.Context, req *computepb.AddRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallPolicyRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/addRule", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// CloneRules copies rules to the specified firewall policy.
+func (c *firewallPoliciesRESTClient) CloneRules(ctx context.Context, req *computepb.CloneRulesFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/cloneRules", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req != nil && req.SourceFirewallPolicy != nil {
+		params.Add("sourceFirewallPolicy", fmt.Sprintf("%v", req.GetSourceFirewallPolicy()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified policy.
+func (c *firewallPoliciesRESTClient) Delete(ctx context.Context, req *computepb.DeleteFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified firewall policy.
+func (c *firewallPoliciesRESTClient) Get(ctx context.Context, req *computepb.GetFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPolicy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v", req.GetFirewallPolicy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.FirewallPolicy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetAssociation gets an association with the specified name.
+func (c *firewallPoliciesRESTClient) GetAssociation(ctx context.Context, req *computepb.GetAssociationFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPolicyAssociation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/getAssociation", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Name != nil {
+		params.Add("name", fmt.Sprintf("%v", req.GetName()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.FirewallPolicyAssociation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *firewallPoliciesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/getIamPolicy", req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetRule gets a rule of the specified priority.
+func (c *firewallPoliciesRESTClient) GetRule(ctx context.Context, req *computepb.GetRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPolicyRule, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/getRule", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Priority != nil {
+		params.Add("priority", fmt.Sprintf("%v", req.GetPriority()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.FirewallPolicyRule{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a new policy in the specified project using the data included in the request.
+func (c *firewallPoliciesRESTClient) Insert(ctx context.Context, req *computepb.InsertFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies")
+
+	params := url.Values{}
+	if req != nil && req.ParentId != nil {
+		params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists all the policies that have been configured for the specified project.
+func (c *firewallPoliciesRESTClient) List(ctx context.Context, req *computepb.ListFirewallPoliciesRequest, opts ...gax.CallOption) (*computepb.FirewallPolicyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies")
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ParentId != nil {
+		params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.FirewallPolicyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListAssociations lists associations of a specified target, i.e., organization or folder.
+func (c *firewallPoliciesRESTClient) ListAssociations(ctx context.Context, req *computepb.ListAssociationsFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.FirewallPoliciesListAssociationsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/listAssociations")
+
+	params := url.Values{}
+	if req != nil && req.TargetResource != nil {
+		params.Add("targetResource", fmt.Sprintf("%v", req.GetTargetResource()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.FirewallPoliciesListAssociationsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Move moves the specified firewall policy.
+func (c *firewallPoliciesRESTClient) Move(ctx context.Context, req *computepb.MoveFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/move", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.ParentId != nil {
+		params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified policy with the data included in the request.
+func (c *firewallPoliciesRESTClient) Patch(ctx context.Context, req *computepb.PatchFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// PatchRule patches a rule of the specified priority.
+func (c *firewallPoliciesRESTClient) PatchRule(ctx context.Context, req *computepb.PatchRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallPolicyRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/patchRule", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Priority != nil {
+		params.Add("priority", fmt.Sprintf("%v", req.GetPriority()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveAssociation removes an association for the specified firewall policy.
+func (c *firewallPoliciesRESTClient) RemoveAssociation(ctx context.Context, req *computepb.RemoveAssociationFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/removeAssociation", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Name != nil {
+		params.Add("name", fmt.Sprintf("%v", req.GetName()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveRule deletes a rule of the specified priority.
+func (c *firewallPoliciesRESTClient) RemoveRule(ctx context.Context, req *computepb.RemoveRuleFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/removeRule", req.GetFirewallPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Priority != nil {
+		params.Add("priority", fmt.Sprintf("%v", req.GetPriority()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *firewallPoliciesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalOrganizationSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/setIamPolicy", req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *firewallPoliciesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsFirewallPolicyRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/firewallPolicies/%v/testIamPermissions", req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/firewall_policies_client_example_test.go b/compute/apiv1/firewall_policies_client_example_test.go
new file mode 100644
index 0000000..787e486
--- /dev/null
+++ b/compute/apiv1/firewall_policies_client_example_test.go
@@ -0,0 +1,378 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewFirewallPoliciesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleFirewallPoliciesClient_AddAssociation() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddAssociationFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddAssociation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_AddRule() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddRuleFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_CloneRules() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.CloneRulesFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.CloneRules(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_GetAssociation() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetAssociationFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetAssociation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_GetRule() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRuleFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListFirewallPoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_ListAssociations() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListAssociationsFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListAssociations(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_Move() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.MoveFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Move(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_PatchRule() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRuleFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.PatchRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_RemoveAssociation() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveAssociationFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveAssociation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_RemoveRule() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveRuleFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallPoliciesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsFirewallPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/firewalls_client.go b/compute/apiv1/firewalls_client.go
new file mode 100644
index 0000000..2d76479
--- /dev/null
+++ b/compute/apiv1/firewalls_client.go
@@ -0,0 +1,502 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newFirewallsClientHook clientHook
+
+// FirewallsCallOptions contains the retry settings for each method of FirewallsClient.
+type FirewallsCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+	Update []gax.CallOption
+}
+
+// internalFirewallsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalFirewallsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteFirewallRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetFirewallRequest, ...gax.CallOption) (*computepb.Firewall, error)
+	Insert(context.Context, *computepb.InsertFirewallRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListFirewallsRequest, ...gax.CallOption) (*computepb.FirewallList, error)
+	Patch(context.Context, *computepb.PatchFirewallRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateFirewallRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// FirewallsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Firewalls API.
+type FirewallsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalFirewallsClient
+
+	// The call options for this service.
+	CallOptions *FirewallsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *FirewallsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *FirewallsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *FirewallsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified firewall.
+func (c *FirewallsClient) Delete(ctx context.Context, req *computepb.DeleteFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified firewall.
+func (c *FirewallsClient) Get(ctx context.Context, req *computepb.GetFirewallRequest, opts ...gax.CallOption) (*computepb.Firewall, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a firewall rule in the specified project using the data included in the request.
+func (c *FirewallsClient) Insert(ctx context.Context, req *computepb.InsertFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of firewall rules available to the specified project.
+func (c *FirewallsClient) List(ctx context.Context, req *computepb.ListFirewallsRequest, opts ...gax.CallOption) (*computepb.FirewallList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified firewall rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *FirewallsClient) Patch(ctx context.Context, req *computepb.PatchFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates the specified firewall rule with the data included in the request. Note that all fields will be updated if using PUT, even fields that are not specified. To update individual fields, please use PATCH instead.
+func (c *FirewallsClient) Update(ctx context.Context, req *computepb.UpdateFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type firewallsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewFirewallsRESTClient creates a new firewalls rest client.
+//
+// The Firewalls API.
+func NewFirewallsRESTClient(ctx context.Context, opts ...option.ClientOption) (*FirewallsClient, error) {
+	clientOpts := append(defaultFirewallsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &firewallsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &FirewallsClient{internalClient: c, CallOptions: &FirewallsCallOptions{}}, nil
+}
+
+func defaultFirewallsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *firewallsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *firewallsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *firewallsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified firewall.
+func (c *firewallsRESTClient) Delete(ctx context.Context, req *computepb.DeleteFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/firewalls/%v", req.GetProject(), req.GetFirewall())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified firewall.
+func (c *firewallsRESTClient) Get(ctx context.Context, req *computepb.GetFirewallRequest, opts ...gax.CallOption) (*computepb.Firewall, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/firewalls/%v", req.GetProject(), req.GetFirewall())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Firewall{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a firewall rule in the specified project using the data included in the request.
+func (c *firewallsRESTClient) Insert(ctx context.Context, req *computepb.InsertFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/firewalls", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of firewall rules available to the specified project.
+func (c *firewallsRESTClient) List(ctx context.Context, req *computepb.ListFirewallsRequest, opts ...gax.CallOption) (*computepb.FirewallList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/firewalls", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.FirewallList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified firewall rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *firewallsRESTClient) Patch(ctx context.Context, req *computepb.PatchFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/firewalls/%v", req.GetProject(), req.GetFirewall())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified firewall rule with the data included in the request. Note that all fields will be updated if using PUT, even fields that are not specified. To update individual fields, please use PATCH instead.
+func (c *firewallsRESTClient) Update(ctx context.Context, req *computepb.UpdateFirewallRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetFirewallResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetFirewall() != "" {
+		params.Add("firewall", fmt.Sprintf("%v", req.GetFirewall()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/firewalls_client_example_test.go b/compute/apiv1/firewalls_client_example_test.go
new file mode 100644
index 0000000..e1db038
--- /dev/null
+++ b/compute/apiv1/firewalls_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewFirewallsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleFirewallsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteFirewallRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetFirewallRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertFirewallRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListFirewallsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchFirewallRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleFirewallsClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewFirewallsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateFirewallRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/forwarding_rules_client.go b/compute/apiv1/forwarding_rules_client.go
new file mode 100644
index 0000000..de00115
--- /dev/null
+++ b/compute/apiv1/forwarding_rules_client.go
@@ -0,0 +1,626 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newForwardingRulesClientHook clientHook
+
+// ForwardingRulesCallOptions contains the retry settings for each method of ForwardingRulesClient.
+type ForwardingRulesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+	SetLabels      []gax.CallOption
+	SetTarget      []gax.CallOption
+}
+
+// internalForwardingRulesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalForwardingRulesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListForwardingRulesRequest, ...gax.CallOption) (*computepb.ForwardingRuleAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetForwardingRuleRequest, ...gax.CallOption) (*computepb.ForwardingRule, error)
+	Insert(context.Context, *computepb.InsertForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListForwardingRulesRequest, ...gax.CallOption) (*computepb.ForwardingRuleList, error)
+	Patch(context.Context, *computepb.PatchForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetLabels(context.Context, *computepb.SetLabelsForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetTarget(context.Context, *computepb.SetTargetForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// ForwardingRulesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The ForwardingRules API.
+type ForwardingRulesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalForwardingRulesClient
+
+	// The call options for this service.
+	CallOptions *ForwardingRulesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ForwardingRulesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ForwardingRulesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ForwardingRulesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of forwarding rules.
+func (c *ForwardingRulesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListForwardingRulesRequest, opts ...gax.CallOption) (*computepb.ForwardingRuleAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified ForwardingRule resource.
+func (c *ForwardingRulesClient) Delete(ctx context.Context, req *computepb.DeleteForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified ForwardingRule resource.
+func (c *ForwardingRulesClient) Get(ctx context.Context, req *computepb.GetForwardingRuleRequest, opts ...gax.CallOption) (*computepb.ForwardingRule, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a ForwardingRule resource in the specified project and region using the data included in the request.
+func (c *ForwardingRulesClient) Insert(ctx context.Context, req *computepb.InsertForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of ForwardingRule resources available to the specified project and region.
+func (c *ForwardingRulesClient) List(ctx context.Context, req *computepb.ListForwardingRulesRequest, opts ...gax.CallOption) (*computepb.ForwardingRuleList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified forwarding rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. Currently, you can only patch the network_tier field.
+func (c *ForwardingRulesClient) Patch(ctx context.Context, req *computepb.PatchForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on the specified resource. To learn more about labels, read the Labeling Resources documentation.
+func (c *ForwardingRulesClient) SetLabels(ctx context.Context, req *computepb.SetLabelsForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// SetTarget changes target URL for forwarding rule. The new target should be of the same type as the old target.
+func (c *ForwardingRulesClient) SetTarget(ctx context.Context, req *computepb.SetTargetForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetTarget(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type forwardingRulesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewForwardingRulesRESTClient creates a new forwarding rules rest client.
+//
+// The ForwardingRules API.
+func NewForwardingRulesRESTClient(ctx context.Context, opts ...option.ClientOption) (*ForwardingRulesClient, error) {
+	clientOpts := append(defaultForwardingRulesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &forwardingRulesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ForwardingRulesClient{internalClient: c, CallOptions: &ForwardingRulesCallOptions{}}, nil
+}
+
+func defaultForwardingRulesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *forwardingRulesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *forwardingRulesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *forwardingRulesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of forwarding rules.
+func (c *forwardingRulesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListForwardingRulesRequest, opts ...gax.CallOption) (*computepb.ForwardingRuleAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/forwardingRules", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ForwardingRuleAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified ForwardingRule resource.
+func (c *forwardingRulesRESTClient) Delete(ctx context.Context, req *computepb.DeleteForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules/%v", req.GetProject(), req.GetRegion(), req.GetForwardingRule())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified ForwardingRule resource.
+func (c *forwardingRulesRESTClient) Get(ctx context.Context, req *computepb.GetForwardingRuleRequest, opts ...gax.CallOption) (*computepb.ForwardingRule, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules/%v", req.GetProject(), req.GetRegion(), req.GetForwardingRule())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ForwardingRule{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a ForwardingRule resource in the specified project and region using the data included in the request.
+func (c *forwardingRulesRESTClient) Insert(ctx context.Context, req *computepb.InsertForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetForwardingRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of ForwardingRule resources available to the specified project and region.
+func (c *forwardingRulesRESTClient) List(ctx context.Context, req *computepb.ListForwardingRulesRequest, opts ...gax.CallOption) (*computepb.ForwardingRuleList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ForwardingRuleList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified forwarding rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. Currently, you can only patch the network_tier field.
+func (c *forwardingRulesRESTClient) Patch(ctx context.Context, req *computepb.PatchForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetForwardingRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules/%v", req.GetProject(), req.GetRegion(), req.GetForwardingRule())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on the specified resource. To learn more about labels, read the Labeling Resources documentation.
+func (c *forwardingRulesRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules/%v/setLabels", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetTarget changes target URL for forwarding rule. The new target should be of the same type as the old target.
+func (c *forwardingRulesRESTClient) SetTarget(ctx context.Context, req *computepb.SetTargetForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/forwardingRules/%v/setTarget", req.GetProject(), req.GetRegion(), req.GetForwardingRule())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/forwarding_rules_client_example_test.go b/compute/apiv1/forwarding_rules_client_example_test.go
new file mode 100644
index 0000000..1a2a9a5
--- /dev/null
+++ b/compute/apiv1/forwarding_rules_client_example_test.go
@@ -0,0 +1,188 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewForwardingRulesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleForwardingRulesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListForwardingRulesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListForwardingRulesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleForwardingRulesClient_SetTarget() {
+	ctx := context.Background()
+	c, err := compute.NewForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetTargetForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetTarget(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/gapic_metadata.json b/compute/apiv1/gapic_metadata.json
new file mode 100644
index 0000000..6474e15
--- /dev/null
+++ b/compute/apiv1/gapic_metadata.json
@@ -0,0 +1,3581 @@
+{
+  "schema": "1.0",
+  "comment": "This file maps proto services/RPCs to the corresponding library clients/methods.",
+  "language": "go",
+  "protoPackage": "google.cloud.compute.v1",
+  "libraryPackage": "cloud.google.com/go/compute/apiv1",
+  "services": {
+    "AcceleratorTypes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "AcceleratorTypesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Addresses": {
+      "clients": {
+        "rest": {
+          "libraryClient": "AddressesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Autoscalers": {
+      "clients": {
+        "rest": {
+          "libraryClient": "AutoscalersClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "BackendBuckets": {
+      "clients": {
+        "rest": {
+          "libraryClient": "BackendBucketsClient",
+          "rpcs": {
+            "AddSignedUrlKey": {
+              "methods": [
+                "AddSignedUrlKey"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DeleteSignedUrlKey": {
+              "methods": [
+                "DeleteSignedUrlKey"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "BackendServices": {
+      "clients": {
+        "rest": {
+          "libraryClient": "BackendServicesClient",
+          "rpcs": {
+            "AddSignedUrlKey": {
+              "methods": [
+                "AddSignedUrlKey"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DeleteSignedUrlKey": {
+              "methods": [
+                "DeleteSignedUrlKey"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetHealth": {
+              "methods": [
+                "GetHealth"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetSecurityPolicy": {
+              "methods": [
+                "SetSecurityPolicy"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "DiskTypes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "DiskTypesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Disks": {
+      "clients": {
+        "rest": {
+          "libraryClient": "DisksClient",
+          "rpcs": {
+            "AddResourcePolicies": {
+              "methods": [
+                "AddResourcePolicies"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "CreateSnapshot": {
+              "methods": [
+                "CreateSnapshot"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "RemoveResourcePolicies": {
+              "methods": [
+                "RemoveResourcePolicies"
+              ]
+            },
+            "Resize": {
+              "methods": [
+                "Resize"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "ExternalVpnGateways": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ExternalVpnGatewaysClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "FirewallPolicies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "FirewallPoliciesClient",
+          "rpcs": {
+            "AddAssociation": {
+              "methods": [
+                "AddAssociation"
+              ]
+            },
+            "AddRule": {
+              "methods": [
+                "AddRule"
+              ]
+            },
+            "CloneRules": {
+              "methods": [
+                "CloneRules"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetAssociation": {
+              "methods": [
+                "GetAssociation"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "GetRule": {
+              "methods": [
+                "GetRule"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListAssociations": {
+              "methods": [
+                "ListAssociations"
+              ]
+            },
+            "Move": {
+              "methods": [
+                "Move"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "PatchRule": {
+              "methods": [
+                "PatchRule"
+              ]
+            },
+            "RemoveAssociation": {
+              "methods": [
+                "RemoveAssociation"
+              ]
+            },
+            "RemoveRule": {
+              "methods": [
+                "RemoveRule"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Firewalls": {
+      "clients": {
+        "rest": {
+          "libraryClient": "FirewallsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "ForwardingRules": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ForwardingRulesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "SetTarget": {
+              "methods": [
+                "SetTarget"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "GlobalAddresses": {
+      "clients": {
+        "rest": {
+          "libraryClient": "GlobalAddressesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "GlobalForwardingRules": {
+      "clients": {
+        "rest": {
+          "libraryClient": "GlobalForwardingRulesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "SetTarget": {
+              "methods": [
+                "SetTarget"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "GlobalNetworkEndpointGroups": {
+      "clients": {
+        "rest": {
+          "libraryClient": "GlobalNetworkEndpointGroupsClient",
+          "rpcs": {
+            "AttachNetworkEndpoints": {
+              "methods": [
+                "AttachNetworkEndpoints"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DetachNetworkEndpoints": {
+              "methods": [
+                "DetachNetworkEndpoints"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListNetworkEndpoints": {
+              "methods": [
+                "ListNetworkEndpoints"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "GlobalOperations": {
+      "clients": {
+        "rest": {
+          "libraryClient": "GlobalOperationsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Wait": {
+              "methods": [
+                "Wait"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "GlobalOrganizationOperations": {
+      "clients": {
+        "rest": {
+          "libraryClient": "GlobalOrganizationOperationsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "GlobalPublicDelegatedPrefixes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "GlobalPublicDelegatedPrefixesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "HealthChecks": {
+      "clients": {
+        "rest": {
+          "libraryClient": "HealthChecksClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Images": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ImagesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Deprecate": {
+              "methods": [
+                "Deprecate"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetFromFamily": {
+              "methods": [
+                "GetFromFamily"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "InstanceGroupManagers": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InstanceGroupManagersClient",
+          "rpcs": {
+            "AbandonInstances": {
+              "methods": [
+                "AbandonInstances"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "ApplyUpdatesToInstances": {
+              "methods": [
+                "ApplyUpdatesToInstances"
+              ]
+            },
+            "CreateInstances": {
+              "methods": [
+                "CreateInstances"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DeleteInstances": {
+              "methods": [
+                "DeleteInstances"
+              ]
+            },
+            "DeletePerInstanceConfigs": {
+              "methods": [
+                "DeletePerInstanceConfigs"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListErrors": {
+              "methods": [
+                "ListErrors"
+              ]
+            },
+            "ListManagedInstances": {
+              "methods": [
+                "ListManagedInstances"
+              ]
+            },
+            "ListPerInstanceConfigs": {
+              "methods": [
+                "ListPerInstanceConfigs"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "PatchPerInstanceConfigs": {
+              "methods": [
+                "PatchPerInstanceConfigs"
+              ]
+            },
+            "RecreateInstances": {
+              "methods": [
+                "RecreateInstances"
+              ]
+            },
+            "Resize": {
+              "methods": [
+                "Resize"
+              ]
+            },
+            "SetInstanceTemplate": {
+              "methods": [
+                "SetInstanceTemplate"
+              ]
+            },
+            "SetTargetPools": {
+              "methods": [
+                "SetTargetPools"
+              ]
+            },
+            "UpdatePerInstanceConfigs": {
+              "methods": [
+                "UpdatePerInstanceConfigs"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "InstanceGroups": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InstanceGroupsClient",
+          "rpcs": {
+            "AddInstances": {
+              "methods": [
+                "AddInstances"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListInstances": {
+              "methods": [
+                "ListInstances"
+              ]
+            },
+            "RemoveInstances": {
+              "methods": [
+                "RemoveInstances"
+              ]
+            },
+            "SetNamedPorts": {
+              "methods": [
+                "SetNamedPorts"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "InstanceTemplates": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InstanceTemplatesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Instances": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InstancesClient",
+          "rpcs": {
+            "AddAccessConfig": {
+              "methods": [
+                "AddAccessConfig"
+              ]
+            },
+            "AddResourcePolicies": {
+              "methods": [
+                "AddResourcePolicies"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "AttachDisk": {
+              "methods": [
+                "AttachDisk"
+              ]
+            },
+            "BulkInsert": {
+              "methods": [
+                "BulkInsert"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DeleteAccessConfig": {
+              "methods": [
+                "DeleteAccessConfig"
+              ]
+            },
+            "DetachDisk": {
+              "methods": [
+                "DetachDisk"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetEffectiveFirewalls": {
+              "methods": [
+                "GetEffectiveFirewalls"
+              ]
+            },
+            "GetGuestAttributes": {
+              "methods": [
+                "GetGuestAttributes"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "GetScreenshot": {
+              "methods": [
+                "GetScreenshot"
+              ]
+            },
+            "GetSerialPortOutput": {
+              "methods": [
+                "GetSerialPortOutput"
+              ]
+            },
+            "GetShieldedInstanceIdentity": {
+              "methods": [
+                "GetShieldedInstanceIdentity"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListReferrers": {
+              "methods": [
+                "ListReferrers"
+              ]
+            },
+            "RemoveResourcePolicies": {
+              "methods": [
+                "RemoveResourcePolicies"
+              ]
+            },
+            "Reset": {
+              "methods": [
+                "Reset"
+              ]
+            },
+            "SetDeletionProtection": {
+              "methods": [
+                "SetDeletionProtection"
+              ]
+            },
+            "SetDiskAutoDelete": {
+              "methods": [
+                "SetDiskAutoDelete"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "SetMachineResources": {
+              "methods": [
+                "SetMachineResources"
+              ]
+            },
+            "SetMachineType": {
+              "methods": [
+                "SetMachineType"
+              ]
+            },
+            "SetMetadata": {
+              "methods": [
+                "SetMetadata"
+              ]
+            },
+            "SetMinCpuPlatform": {
+              "methods": [
+                "SetMinCpuPlatform"
+              ]
+            },
+            "SetScheduling": {
+              "methods": [
+                "SetScheduling"
+              ]
+            },
+            "SetServiceAccount": {
+              "methods": [
+                "SetServiceAccount"
+              ]
+            },
+            "SetShieldedInstanceIntegrityPolicy": {
+              "methods": [
+                "SetShieldedInstanceIntegrityPolicy"
+              ]
+            },
+            "SetTags": {
+              "methods": [
+                "SetTags"
+              ]
+            },
+            "SimulateMaintenanceEvent": {
+              "methods": [
+                "SimulateMaintenanceEvent"
+              ]
+            },
+            "Start": {
+              "methods": [
+                "Start"
+              ]
+            },
+            "StartWithEncryptionKey": {
+              "methods": [
+                "StartWithEncryptionKey"
+              ]
+            },
+            "Stop": {
+              "methods": [
+                "Stop"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            },
+            "UpdateAccessConfig": {
+              "methods": [
+                "UpdateAccessConfig"
+              ]
+            },
+            "UpdateDisplayDevice": {
+              "methods": [
+                "UpdateDisplayDevice"
+              ]
+            },
+            "UpdateNetworkInterface": {
+              "methods": [
+                "UpdateNetworkInterface"
+              ]
+            },
+            "UpdateShieldedInstanceConfig": {
+              "methods": [
+                "UpdateShieldedInstanceConfig"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "InterconnectAttachments": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InterconnectAttachmentsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "InterconnectLocations": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InterconnectLocationsClient",
+          "rpcs": {
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Interconnects": {
+      "clients": {
+        "rest": {
+          "libraryClient": "InterconnectsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetDiagnostics": {
+              "methods": [
+                "GetDiagnostics"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "LicenseCodes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "LicenseCodesClient",
+          "rpcs": {
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Licenses": {
+      "clients": {
+        "rest": {
+          "libraryClient": "LicensesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "MachineTypes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "MachineTypesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "NetworkEndpointGroups": {
+      "clients": {
+        "rest": {
+          "libraryClient": "NetworkEndpointGroupsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "AttachNetworkEndpoints": {
+              "methods": [
+                "AttachNetworkEndpoints"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DetachNetworkEndpoints": {
+              "methods": [
+                "DetachNetworkEndpoints"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListNetworkEndpoints": {
+              "methods": [
+                "ListNetworkEndpoints"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Networks": {
+      "clients": {
+        "rest": {
+          "libraryClient": "NetworksClient",
+          "rpcs": {
+            "AddPeering": {
+              "methods": [
+                "AddPeering"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetEffectiveFirewalls": {
+              "methods": [
+                "GetEffectiveFirewalls"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListPeeringRoutes": {
+              "methods": [
+                "ListPeeringRoutes"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "RemovePeering": {
+              "methods": [
+                "RemovePeering"
+              ]
+            },
+            "SwitchToCustomMode": {
+              "methods": [
+                "SwitchToCustomMode"
+              ]
+            },
+            "UpdatePeering": {
+              "methods": [
+                "UpdatePeering"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "NodeGroups": {
+      "clients": {
+        "rest": {
+          "libraryClient": "NodeGroupsClient",
+          "rpcs": {
+            "AddNodes": {
+              "methods": [
+                "AddNodes"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DeleteNodes": {
+              "methods": [
+                "DeleteNodes"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListNodes": {
+              "methods": [
+                "ListNodes"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetNodeTemplate": {
+              "methods": [
+                "SetNodeTemplate"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "NodeTemplates": {
+      "clients": {
+        "rest": {
+          "libraryClient": "NodeTemplatesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "NodeTypes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "NodeTypesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "PacketMirrorings": {
+      "clients": {
+        "rest": {
+          "libraryClient": "PacketMirroringsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Projects": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ProjectsClient",
+          "rpcs": {
+            "DisableXpnHost": {
+              "methods": [
+                "DisableXpnHost"
+              ]
+            },
+            "DisableXpnResource": {
+              "methods": [
+                "DisableXpnResource"
+              ]
+            },
+            "EnableXpnHost": {
+              "methods": [
+                "EnableXpnHost"
+              ]
+            },
+            "EnableXpnResource": {
+              "methods": [
+                "EnableXpnResource"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetXpnHost": {
+              "methods": [
+                "GetXpnHost"
+              ]
+            },
+            "GetXpnResources": {
+              "methods": [
+                "GetXpnResources"
+              ]
+            },
+            "ListXpnHosts": {
+              "methods": [
+                "ListXpnHosts"
+              ]
+            },
+            "MoveDisk": {
+              "methods": [
+                "MoveDisk"
+              ]
+            },
+            "MoveInstance": {
+              "methods": [
+                "MoveInstance"
+              ]
+            },
+            "SetCommonInstanceMetadata": {
+              "methods": [
+                "SetCommonInstanceMetadata"
+              ]
+            },
+            "SetDefaultNetworkTier": {
+              "methods": [
+                "SetDefaultNetworkTier"
+              ]
+            },
+            "SetUsageExportBucket": {
+              "methods": [
+                "SetUsageExportBucket"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "PublicAdvertisedPrefixes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "PublicAdvertisedPrefixesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "PublicDelegatedPrefixes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "PublicDelegatedPrefixesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionAutoscalers": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionAutoscalersClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionBackendServices": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionBackendServicesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetHealth": {
+              "methods": [
+                "GetHealth"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionCommitments": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionCommitmentsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionDiskTypes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionDiskTypesClient",
+          "rpcs": {
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionDisks": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionDisksClient",
+          "rpcs": {
+            "AddResourcePolicies": {
+              "methods": [
+                "AddResourcePolicies"
+              ]
+            },
+            "CreateSnapshot": {
+              "methods": [
+                "CreateSnapshot"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "RemoveResourcePolicies": {
+              "methods": [
+                "RemoveResourcePolicies"
+              ]
+            },
+            "Resize": {
+              "methods": [
+                "Resize"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionHealthCheckServices": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionHealthCheckServicesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionHealthChecks": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionHealthChecksClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionInstanceGroupManagers": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionInstanceGroupManagersClient",
+          "rpcs": {
+            "AbandonInstances": {
+              "methods": [
+                "AbandonInstances"
+              ]
+            },
+            "ApplyUpdatesToInstances": {
+              "methods": [
+                "ApplyUpdatesToInstances"
+              ]
+            },
+            "CreateInstances": {
+              "methods": [
+                "CreateInstances"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "DeleteInstances": {
+              "methods": [
+                "DeleteInstances"
+              ]
+            },
+            "DeletePerInstanceConfigs": {
+              "methods": [
+                "DeletePerInstanceConfigs"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListErrors": {
+              "methods": [
+                "ListErrors"
+              ]
+            },
+            "ListManagedInstances": {
+              "methods": [
+                "ListManagedInstances"
+              ]
+            },
+            "ListPerInstanceConfigs": {
+              "methods": [
+                "ListPerInstanceConfigs"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "PatchPerInstanceConfigs": {
+              "methods": [
+                "PatchPerInstanceConfigs"
+              ]
+            },
+            "RecreateInstances": {
+              "methods": [
+                "RecreateInstances"
+              ]
+            },
+            "Resize": {
+              "methods": [
+                "Resize"
+              ]
+            },
+            "SetInstanceTemplate": {
+              "methods": [
+                "SetInstanceTemplate"
+              ]
+            },
+            "SetTargetPools": {
+              "methods": [
+                "SetTargetPools"
+              ]
+            },
+            "UpdatePerInstanceConfigs": {
+              "methods": [
+                "UpdatePerInstanceConfigs"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionInstanceGroups": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionInstanceGroupsClient",
+          "rpcs": {
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListInstances": {
+              "methods": [
+                "ListInstances"
+              ]
+            },
+            "SetNamedPorts": {
+              "methods": [
+                "SetNamedPorts"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionInstances": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionInstancesClient",
+          "rpcs": {
+            "BulkInsert": {
+              "methods": [
+                "BulkInsert"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionNetworkEndpointGroups": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionNetworkEndpointGroupsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionNotificationEndpoints": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionNotificationEndpointsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionOperations": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionOperationsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Wait": {
+              "methods": [
+                "Wait"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionSslCertificates": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionSslCertificatesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionTargetHttpProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionTargetHttpProxiesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetUrlMap": {
+              "methods": [
+                "SetUrlMap"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionTargetHttpsProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionTargetHttpsProxiesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetSslCertificates": {
+              "methods": [
+                "SetSslCertificates"
+              ]
+            },
+            "SetUrlMap": {
+              "methods": [
+                "SetUrlMap"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "RegionUrlMaps": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionUrlMapsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            },
+            "Validate": {
+              "methods": [
+                "Validate"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Regions": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RegionsClient",
+          "rpcs": {
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Reservations": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ReservationsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Resize": {
+              "methods": [
+                "Resize"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "ResourcePolicies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ResourcePoliciesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Routers": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RoutersClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetNatMappingInfo": {
+              "methods": [
+                "GetNatMappingInfo"
+              ]
+            },
+            "GetRouterStatus": {
+              "methods": [
+                "GetRouterStatus"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Preview": {
+              "methods": [
+                "Preview"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Routes": {
+      "clients": {
+        "rest": {
+          "libraryClient": "RoutesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "SecurityPolicies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "SecurityPoliciesClient",
+          "rpcs": {
+            "AddRule": {
+              "methods": [
+                "AddRule"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetRule": {
+              "methods": [
+                "GetRule"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListPreconfiguredExpressionSets": {
+              "methods": [
+                "ListPreconfiguredExpressionSets"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "PatchRule": {
+              "methods": [
+                "PatchRule"
+              ]
+            },
+            "RemoveRule": {
+              "methods": [
+                "RemoveRule"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Snapshots": {
+      "clients": {
+        "rest": {
+          "libraryClient": "SnapshotsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "SslCertificates": {
+      "clients": {
+        "rest": {
+          "libraryClient": "SslCertificatesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "SslPolicies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "SslPoliciesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListAvailableFeatures": {
+              "methods": [
+                "ListAvailableFeatures"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Subnetworks": {
+      "clients": {
+        "rest": {
+          "libraryClient": "SubnetworksClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "ExpandIpCidrRange": {
+              "methods": [
+                "ExpandIpCidrRange"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetIamPolicy": {
+              "methods": [
+                "GetIamPolicy"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "ListUsable": {
+              "methods": [
+                "ListUsable"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetIamPolicy": {
+              "methods": [
+                "SetIamPolicy"
+              ]
+            },
+            "SetPrivateIpGoogleAccess": {
+              "methods": [
+                "SetPrivateIpGoogleAccess"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetGrpcProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetGrpcProxiesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetHttpProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetHttpProxiesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetUrlMap": {
+              "methods": [
+                "SetUrlMap"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetHttpsProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetHttpsProxiesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "SetQuicOverride": {
+              "methods": [
+                "SetQuicOverride"
+              ]
+            },
+            "SetSslCertificates": {
+              "methods": [
+                "SetSslCertificates"
+              ]
+            },
+            "SetSslPolicy": {
+              "methods": [
+                "SetSslPolicy"
+              ]
+            },
+            "SetUrlMap": {
+              "methods": [
+                "SetUrlMap"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetInstances": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetInstancesClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetPools": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetPoolsClient",
+          "rpcs": {
+            "AddHealthCheck": {
+              "methods": [
+                "AddHealthCheck"
+              ]
+            },
+            "AddInstance": {
+              "methods": [
+                "AddInstance"
+              ]
+            },
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetHealth": {
+              "methods": [
+                "GetHealth"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "RemoveHealthCheck": {
+              "methods": [
+                "RemoveHealthCheck"
+              ]
+            },
+            "RemoveInstance": {
+              "methods": [
+                "RemoveInstance"
+              ]
+            },
+            "SetBackup": {
+              "methods": [
+                "SetBackup"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetSslProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetSslProxiesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetBackendService": {
+              "methods": [
+                "SetBackendService"
+              ]
+            },
+            "SetProxyHeader": {
+              "methods": [
+                "SetProxyHeader"
+              ]
+            },
+            "SetSslCertificates": {
+              "methods": [
+                "SetSslCertificates"
+              ]
+            },
+            "SetSslPolicy": {
+              "methods": [
+                "SetSslPolicy"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetTcpProxies": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetTcpProxiesClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetBackendService": {
+              "methods": [
+                "SetBackendService"
+              ]
+            },
+            "SetProxyHeader": {
+              "methods": [
+                "SetProxyHeader"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "TargetVpnGateways": {
+      "clients": {
+        "rest": {
+          "libraryClient": "TargetVpnGatewaysClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "UrlMaps": {
+      "clients": {
+        "rest": {
+          "libraryClient": "UrlMapsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "InvalidateCache": {
+              "methods": [
+                "InvalidateCache"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Patch": {
+              "methods": [
+                "Patch"
+              ]
+            },
+            "Update": {
+              "methods": [
+                "Update"
+              ]
+            },
+            "Validate": {
+              "methods": [
+                "Validate"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "VpnGateways": {
+      "clients": {
+        "rest": {
+          "libraryClient": "VpnGatewaysClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "GetStatus": {
+              "methods": [
+                "GetStatus"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "SetLabels": {
+              "methods": [
+                "SetLabels"
+              ]
+            },
+            "TestIamPermissions": {
+              "methods": [
+                "TestIamPermissions"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "VpnTunnels": {
+      "clients": {
+        "rest": {
+          "libraryClient": "VpnTunnelsClient",
+          "rpcs": {
+            "AggregatedList": {
+              "methods": [
+                "AggregatedList"
+              ]
+            },
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "Insert": {
+              "methods": [
+                "Insert"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "ZoneOperations": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ZoneOperationsClient",
+          "rpcs": {
+            "Delete": {
+              "methods": [
+                "Delete"
+              ]
+            },
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            },
+            "Wait": {
+              "methods": [
+                "Wait"
+              ]
+            }
+          }
+        }
+      }
+    },
+    "Zones": {
+      "clients": {
+        "rest": {
+          "libraryClient": "ZonesClient",
+          "rpcs": {
+            "Get": {
+              "methods": [
+                "Get"
+              ]
+            },
+            "List": {
+              "methods": [
+                "List"
+              ]
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/compute/apiv1/global_addresses_client.go b/compute/apiv1/global_addresses_client.go
new file mode 100644
index 0000000..cc87746
--- /dev/null
+++ b/compute/apiv1/global_addresses_client.go
@@ -0,0 +1,380 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newGlobalAddressesClientHook clientHook
+
+// GlobalAddressesCallOptions contains the retry settings for each method of GlobalAddressesClient.
+type GlobalAddressesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+}
+
+// internalGlobalAddressesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalGlobalAddressesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteGlobalAddressRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetGlobalAddressRequest, ...gax.CallOption) (*computepb.Address, error)
+	Insert(context.Context, *computepb.InsertGlobalAddressRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListGlobalAddressesRequest, ...gax.CallOption) (*computepb.AddressList, error)
+}
+
+// GlobalAddressesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The GlobalAddresses API.
+type GlobalAddressesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalGlobalAddressesClient
+
+	// The call options for this service.
+	CallOptions *GlobalAddressesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *GlobalAddressesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *GlobalAddressesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *GlobalAddressesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified address resource.
+func (c *GlobalAddressesClient) Delete(ctx context.Context, req *computepb.DeleteGlobalAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified address resource. Gets a list of available addresses by making a list() request.
+func (c *GlobalAddressesClient) Get(ctx context.Context, req *computepb.GetGlobalAddressRequest, opts ...gax.CallOption) (*computepb.Address, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates an address resource in the specified project by using the data included in the request.
+func (c *GlobalAddressesClient) Insert(ctx context.Context, req *computepb.InsertGlobalAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of global addresses.
+func (c *GlobalAddressesClient) List(ctx context.Context, req *computepb.ListGlobalAddressesRequest, opts ...gax.CallOption) (*computepb.AddressList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type globalAddressesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewGlobalAddressesRESTClient creates a new global addresses rest client.
+//
+// The GlobalAddresses API.
+func NewGlobalAddressesRESTClient(ctx context.Context, opts ...option.ClientOption) (*GlobalAddressesClient, error) {
+	clientOpts := append(defaultGlobalAddressesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &globalAddressesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &GlobalAddressesClient{internalClient: c, CallOptions: &GlobalAddressesCallOptions{}}, nil
+}
+
+func defaultGlobalAddressesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *globalAddressesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *globalAddressesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *globalAddressesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified address resource.
+func (c *globalAddressesRESTClient) Delete(ctx context.Context, req *computepb.DeleteGlobalAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/addresses/%v", req.GetProject(), req.GetAddress())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified address resource. Gets a list of available addresses by making a list() request.
+func (c *globalAddressesRESTClient) Get(ctx context.Context, req *computepb.GetGlobalAddressRequest, opts ...gax.CallOption) (*computepb.Address, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/addresses/%v", req.GetProject(), req.GetAddress())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Address{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an address resource in the specified project by using the data included in the request.
+func (c *globalAddressesRESTClient) Insert(ctx context.Context, req *computepb.InsertGlobalAddressRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAddressResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/addresses", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of global addresses.
+func (c *globalAddressesRESTClient) List(ctx context.Context, req *computepb.ListGlobalAddressesRequest, opts ...gax.CallOption) (*computepb.AddressList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/addresses", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.AddressList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/global_addresses_client_example_test.go b/compute/apiv1/global_addresses_client_example_test.go
new file mode 100644
index 0000000..a226879
--- /dev/null
+++ b/compute/apiv1/global_addresses_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewGlobalAddressesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleGlobalAddressesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteGlobalAddressRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalAddressesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGlobalAddressRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalAddressesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertGlobalAddressRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalAddressesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalAddressesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListGlobalAddressesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/global_forwarding_rules_client.go b/compute/apiv1/global_forwarding_rules_client.go
new file mode 100644
index 0000000..3112650
--- /dev/null
+++ b/compute/apiv1/global_forwarding_rules_client.go
@@ -0,0 +1,547 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newGlobalForwardingRulesClientHook clientHook
+
+// GlobalForwardingRulesCallOptions contains the retry settings for each method of GlobalForwardingRulesClient.
+type GlobalForwardingRulesCallOptions struct {
+	Delete    []gax.CallOption
+	Get       []gax.CallOption
+	Insert    []gax.CallOption
+	List      []gax.CallOption
+	Patch     []gax.CallOption
+	SetLabels []gax.CallOption
+	SetTarget []gax.CallOption
+}
+
+// internalGlobalForwardingRulesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalGlobalForwardingRulesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteGlobalForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetGlobalForwardingRuleRequest, ...gax.CallOption) (*computepb.ForwardingRule, error)
+	Insert(context.Context, *computepb.InsertGlobalForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListGlobalForwardingRulesRequest, ...gax.CallOption) (*computepb.ForwardingRuleList, error)
+	Patch(context.Context, *computepb.PatchGlobalForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetLabels(context.Context, *computepb.SetLabelsGlobalForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetTarget(context.Context, *computepb.SetTargetGlobalForwardingRuleRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// GlobalForwardingRulesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The GlobalForwardingRules API.
+type GlobalForwardingRulesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalGlobalForwardingRulesClient
+
+	// The call options for this service.
+	CallOptions *GlobalForwardingRulesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *GlobalForwardingRulesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *GlobalForwardingRulesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *GlobalForwardingRulesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified GlobalForwardingRule resource.
+func (c *GlobalForwardingRulesClient) Delete(ctx context.Context, req *computepb.DeleteGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified GlobalForwardingRule resource. Gets a list of available forwarding rules by making a list() request.
+func (c *GlobalForwardingRulesClient) Get(ctx context.Context, req *computepb.GetGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.ForwardingRule, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a GlobalForwardingRule resource in the specified project using the data included in the request.
+func (c *GlobalForwardingRulesClient) Insert(ctx context.Context, req *computepb.InsertGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of GlobalForwardingRule resources available to the specified project.
+func (c *GlobalForwardingRulesClient) List(ctx context.Context, req *computepb.ListGlobalForwardingRulesRequest, opts ...gax.CallOption) (*computepb.ForwardingRuleList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified forwarding rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. Currently, you can only patch the network_tier field.
+func (c *GlobalForwardingRulesClient) Patch(ctx context.Context, req *computepb.PatchGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on the specified resource. To learn more about labels, read the Labeling Resources documentation.
+func (c *GlobalForwardingRulesClient) SetLabels(ctx context.Context, req *computepb.SetLabelsGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// SetTarget changes target URL for the GlobalForwardingRule resource. The new target should be of the same type as the old target.
+func (c *GlobalForwardingRulesClient) SetTarget(ctx context.Context, req *computepb.SetTargetGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetTarget(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type globalForwardingRulesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewGlobalForwardingRulesRESTClient creates a new global forwarding rules rest client.
+//
+// The GlobalForwardingRules API.
+func NewGlobalForwardingRulesRESTClient(ctx context.Context, opts ...option.ClientOption) (*GlobalForwardingRulesClient, error) {
+	clientOpts := append(defaultGlobalForwardingRulesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &globalForwardingRulesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &GlobalForwardingRulesClient{internalClient: c, CallOptions: &GlobalForwardingRulesCallOptions{}}, nil
+}
+
+func defaultGlobalForwardingRulesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *globalForwardingRulesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *globalForwardingRulesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *globalForwardingRulesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified GlobalForwardingRule resource.
+func (c *globalForwardingRulesRESTClient) Delete(ctx context.Context, req *computepb.DeleteGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules/%v", req.GetProject(), req.GetForwardingRule())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified GlobalForwardingRule resource. Gets a list of available forwarding rules by making a list() request.
+func (c *globalForwardingRulesRESTClient) Get(ctx context.Context, req *computepb.GetGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.ForwardingRule, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules/%v", req.GetProject(), req.GetForwardingRule())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ForwardingRule{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a GlobalForwardingRule resource in the specified project using the data included in the request.
+func (c *globalForwardingRulesRESTClient) Insert(ctx context.Context, req *computepb.InsertGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetForwardingRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of GlobalForwardingRule resources available to the specified project.
+func (c *globalForwardingRulesRESTClient) List(ctx context.Context, req *computepb.ListGlobalForwardingRulesRequest, opts ...gax.CallOption) (*computepb.ForwardingRuleList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ForwardingRuleList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified forwarding rule with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules. Currently, you can only patch the network_tier field.
+func (c *globalForwardingRulesRESTClient) Patch(ctx context.Context, req *computepb.PatchGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetForwardingRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules/%v", req.GetProject(), req.GetForwardingRule())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on the specified resource. To learn more about labels, read the Labeling Resources documentation.
+func (c *globalForwardingRulesRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules/%v/setLabels", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetTarget changes target URL for the GlobalForwardingRule resource. The new target should be of the same type as the old target.
+func (c *globalForwardingRulesRESTClient) SetTarget(ctx context.Context, req *computepb.SetTargetGlobalForwardingRuleRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/forwardingRules/%v/setTarget", req.GetProject(), req.GetForwardingRule())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/global_forwarding_rules_client_example_test.go b/compute/apiv1/global_forwarding_rules_client_example_test.go
new file mode 100644
index 0000000..13f8bce
--- /dev/null
+++ b/compute/apiv1/global_forwarding_rules_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewGlobalForwardingRulesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleGlobalForwardingRulesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteGlobalForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalForwardingRulesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGlobalForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalForwardingRulesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertGlobalForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalForwardingRulesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListGlobalForwardingRulesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalForwardingRulesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchGlobalForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalForwardingRulesClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsGlobalForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalForwardingRulesClient_SetTarget() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalForwardingRulesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetTargetGlobalForwardingRuleRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetTarget(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/global_network_endpoint_groups_client.go b/compute/apiv1/global_network_endpoint_groups_client.go
new file mode 100644
index 0000000..54f22cc
--- /dev/null
+++ b/compute/apiv1/global_network_endpoint_groups_client.go
@@ -0,0 +1,565 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newGlobalNetworkEndpointGroupsClientHook clientHook
+
+// GlobalNetworkEndpointGroupsCallOptions contains the retry settings for each method of GlobalNetworkEndpointGroupsClient.
+type GlobalNetworkEndpointGroupsCallOptions struct {
+	AttachNetworkEndpoints []gax.CallOption
+	Delete                 []gax.CallOption
+	DetachNetworkEndpoints []gax.CallOption
+	Get                    []gax.CallOption
+	Insert                 []gax.CallOption
+	List                   []gax.CallOption
+	ListNetworkEndpoints   []gax.CallOption
+}
+
+// internalGlobalNetworkEndpointGroupsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalGlobalNetworkEndpointGroupsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AttachNetworkEndpoints(context.Context, *computepb.AttachNetworkEndpointsGlobalNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteGlobalNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DetachNetworkEndpoints(context.Context, *computepb.DetachNetworkEndpointsGlobalNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetGlobalNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroup, error)
+	Insert(context.Context, *computepb.InsertGlobalNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListGlobalNetworkEndpointGroupsRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error)
+	ListNetworkEndpoints(context.Context, *computepb.ListNetworkEndpointsGlobalNetworkEndpointGroupsRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroupsListNetworkEndpoints, error)
+}
+
+// GlobalNetworkEndpointGroupsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The GlobalNetworkEndpointGroups API.
+type GlobalNetworkEndpointGroupsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalGlobalNetworkEndpointGroupsClient
+
+	// The call options for this service.
+	CallOptions *GlobalNetworkEndpointGroupsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *GlobalNetworkEndpointGroupsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *GlobalNetworkEndpointGroupsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *GlobalNetworkEndpointGroupsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AttachNetworkEndpoints attach a network endpoint to the specified network endpoint group.
+func (c *GlobalNetworkEndpointGroupsClient) AttachNetworkEndpoints(ctx context.Context, req *computepb.AttachNetworkEndpointsGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AttachNetworkEndpoints(ctx, req, opts...)
+}
+
+// Delete deletes the specified network endpoint group.Note that the NEG cannot be deleted if there are backend services referencing it.
+func (c *GlobalNetworkEndpointGroupsClient) Delete(ctx context.Context, req *computepb.DeleteGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DetachNetworkEndpoints detach the network endpoint from the specified network endpoint group.
+func (c *GlobalNetworkEndpointGroupsClient) DetachNetworkEndpoints(ctx context.Context, req *computepb.DetachNetworkEndpointsGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DetachNetworkEndpoints(ctx, req, opts...)
+}
+
+// Get returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request.
+func (c *GlobalNetworkEndpointGroupsClient) Get(ctx context.Context, req *computepb.GetGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroup, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a network endpoint group in the specified project using the parameters that are included in the request.
+func (c *GlobalNetworkEndpointGroupsClient) Insert(ctx context.Context, req *computepb.InsertGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of network endpoint groups that are located in the specified project.
+func (c *GlobalNetworkEndpointGroupsClient) List(ctx context.Context, req *computepb.ListGlobalNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListNetworkEndpoints lists the network endpoints in the specified network endpoint group.
+func (c *GlobalNetworkEndpointGroupsClient) ListNetworkEndpoints(ctx context.Context, req *computepb.ListNetworkEndpointsGlobalNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupsListNetworkEndpoints, error) {
+	return c.internalClient.ListNetworkEndpoints(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type globalNetworkEndpointGroupsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewGlobalNetworkEndpointGroupsRESTClient creates a new global network endpoint groups rest client.
+//
+// The GlobalNetworkEndpointGroups API.
+func NewGlobalNetworkEndpointGroupsRESTClient(ctx context.Context, opts ...option.ClientOption) (*GlobalNetworkEndpointGroupsClient, error) {
+	clientOpts := append(defaultGlobalNetworkEndpointGroupsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &globalNetworkEndpointGroupsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &GlobalNetworkEndpointGroupsClient{internalClient: c, CallOptions: &GlobalNetworkEndpointGroupsCallOptions{}}, nil
+}
+
+func defaultGlobalNetworkEndpointGroupsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *globalNetworkEndpointGroupsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *globalNetworkEndpointGroupsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *globalNetworkEndpointGroupsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AttachNetworkEndpoints attach a network endpoint to the specified network endpoint group.
+func (c *globalNetworkEndpointGroupsRESTClient) AttachNetworkEndpoints(ctx context.Context, req *computepb.AttachNetworkEndpointsGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalNetworkEndpointGroupsAttachEndpointsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups/%v/attachNetworkEndpoints", req.GetProject(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified network endpoint group.Note that the NEG cannot be deleted if there are backend services referencing it.
+func (c *globalNetworkEndpointGroupsRESTClient) Delete(ctx context.Context, req *computepb.DeleteGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups/%v", req.GetProject(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DetachNetworkEndpoints detach the network endpoint from the specified network endpoint group.
+func (c *globalNetworkEndpointGroupsRESTClient) DetachNetworkEndpoints(ctx context.Context, req *computepb.DetachNetworkEndpointsGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalNetworkEndpointGroupsDetachEndpointsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups/%v/detachNetworkEndpoints", req.GetProject(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request.
+func (c *globalNetworkEndpointGroupsRESTClient) Get(ctx context.Context, req *computepb.GetGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroup, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups/%v", req.GetProject(), req.GetNetworkEndpointGroup())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroup{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a network endpoint group in the specified project using the parameters that are included in the request.
+func (c *globalNetworkEndpointGroupsRESTClient) Insert(ctx context.Context, req *computepb.InsertGlobalNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkEndpointGroupResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of network endpoint groups that are located in the specified project.
+func (c *globalNetworkEndpointGroupsRESTClient) List(ctx context.Context, req *computepb.ListGlobalNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroupList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListNetworkEndpoints lists the network endpoints in the specified network endpoint group.
+func (c *globalNetworkEndpointGroupsRESTClient) ListNetworkEndpoints(ctx context.Context, req *computepb.ListNetworkEndpointsGlobalNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupsListNetworkEndpoints, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networkEndpointGroups/%v/listNetworkEndpoints", req.GetProject(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroupsListNetworkEndpoints{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/global_network_endpoint_groups_client_example_test.go b/compute/apiv1/global_network_endpoint_groups_client_example_test.go
new file mode 100644
index 0000000..80361d6
--- /dev/null
+++ b/compute/apiv1/global_network_endpoint_groups_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewGlobalNetworkEndpointGroupsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_AttachNetworkEndpoints() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AttachNetworkEndpointsGlobalNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AttachNetworkEndpoints(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteGlobalNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_DetachNetworkEndpoints() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DetachNetworkEndpointsGlobalNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DetachNetworkEndpoints(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGlobalNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertGlobalNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListGlobalNetworkEndpointGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalNetworkEndpointGroupsClient_ListNetworkEndpoints() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNetworkEndpointsGlobalNetworkEndpointGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListNetworkEndpoints(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/global_operations_client.go b/compute/apiv1/global_operations_client.go
new file mode 100644
index 0000000..928eedf
--- /dev/null
+++ b/compute/apiv1/global_operations_client.go
@@ -0,0 +1,449 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newGlobalOperationsClientHook clientHook
+
+// GlobalOperationsCallOptions contains the retry settings for each method of GlobalOperationsClient.
+type GlobalOperationsCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	List           []gax.CallOption
+	Wait           []gax.CallOption
+}
+
+// internalGlobalOperationsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalGlobalOperationsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListGlobalOperationsRequest, ...gax.CallOption) (*computepb.OperationAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteGlobalOperationRequest, ...gax.CallOption) (*computepb.DeleteGlobalOperationResponse, error)
+	Get(context.Context, *computepb.GetGlobalOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListGlobalOperationsRequest, ...gax.CallOption) (*computepb.OperationList, error)
+	Wait(context.Context, *computepb.WaitGlobalOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// GlobalOperationsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The GlobalOperations API.
+type GlobalOperationsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalGlobalOperationsClient
+
+	// The call options for this service.
+	CallOptions *GlobalOperationsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *GlobalOperationsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *GlobalOperationsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *GlobalOperationsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of all operations.
+func (c *GlobalOperationsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListGlobalOperationsRequest, opts ...gax.CallOption) (*computepb.OperationAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified Operations resource.
+func (c *GlobalOperationsClient) Delete(ctx context.Context, req *computepb.DeleteGlobalOperationRequest, opts ...gax.CallOption) (*computepb.DeleteGlobalOperationResponse, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get retrieves the specified Operations resource. Gets a list of operations by making a list() request.
+func (c *GlobalOperationsClient) Get(ctx context.Context, req *computepb.GetGlobalOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of Operation resources contained within the specified project.
+func (c *GlobalOperationsClient) List(ctx context.Context, req *computepb.ListGlobalOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Wait waits for the specified Operation resource to return as DONE or for the request to approach the 2 minute deadline, and retrieves the specified Operation resource. This method differs from the GET method in that it waits for no more than the default deadline (2 minutes) and then returns the current state of the operation, which might be DONE or still in progress.
+//
+// This method is called on a best-effort basis. Specifically:
+//
+//   In uncommon cases, when the server is overloaded, the request might return before the default deadline is reached, or might return after zero seconds.
+//
+//   If the default deadline is reached, there is no guarantee that the operation is actually done when the method returns. Be prepared to retry if the operation is not DONE.
+func (c *GlobalOperationsClient) Wait(ctx context.Context, req *computepb.WaitGlobalOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Wait(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type globalOperationsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewGlobalOperationsRESTClient creates a new global operations rest client.
+//
+// The GlobalOperations API.
+func NewGlobalOperationsRESTClient(ctx context.Context, opts ...option.ClientOption) (*GlobalOperationsClient, error) {
+	clientOpts := append(defaultGlobalOperationsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &globalOperationsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &GlobalOperationsClient{internalClient: c, CallOptions: &GlobalOperationsCallOptions{}}, nil
+}
+
+func defaultGlobalOperationsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *globalOperationsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *globalOperationsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *globalOperationsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of all operations.
+func (c *globalOperationsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListGlobalOperationsRequest, opts ...gax.CallOption) (*computepb.OperationAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/operations", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.OperationAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified Operations resource.
+func (c *globalOperationsRESTClient) Delete(ctx context.Context, req *computepb.DeleteGlobalOperationRequest, opts ...gax.CallOption) (*computepb.DeleteGlobalOperationResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/operations/%v", req.GetProject(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DeleteGlobalOperationResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get retrieves the specified Operations resource. Gets a list of operations by making a list() request.
+func (c *globalOperationsRESTClient) Get(ctx context.Context, req *computepb.GetGlobalOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/operations/%v", req.GetProject(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of Operation resources contained within the specified project.
+func (c *globalOperationsRESTClient) List(ctx context.Context, req *computepb.ListGlobalOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/operations", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.OperationList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Wait waits for the specified Operation resource to return as DONE or for the request to approach the 2 minute deadline, and retrieves the specified Operation resource. This method differs from the GET method in that it waits for no more than the default deadline (2 minutes) and then returns the current state of the operation, which might be DONE or still in progress.
+//
+// This method is called on a best-effort basis. Specifically:
+//
+//   In uncommon cases, when the server is overloaded, the request might return before the default deadline is reached, or might return after zero seconds.
+//
+//   If the default deadline is reached, there is no guarantee that the operation is actually done when the method returns. Be prepared to retry if the operation is not DONE.
+func (c *globalOperationsRESTClient) Wait(ctx context.Context, req *computepb.WaitGlobalOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/operations/%v/wait", req.GetProject(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/global_operations_client_example_test.go b/compute/apiv1/global_operations_client_example_test.go
new file mode 100644
index 0000000..4cb6a78
--- /dev/null
+++ b/compute/apiv1/global_operations_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewGlobalOperationsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleGlobalOperationsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListGlobalOperationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalOperationsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteGlobalOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalOperationsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGlobalOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalOperationsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListGlobalOperationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalOperationsClient_Wait() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.WaitGlobalOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Wait(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/global_organization_operations_client.go b/compute/apiv1/global_organization_operations_client.go
new file mode 100644
index 0000000..94cec22
--- /dev/null
+++ b/compute/apiv1/global_organization_operations_client.go
@@ -0,0 +1,332 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newGlobalOrganizationOperationsClientHook clientHook
+
+// GlobalOrganizationOperationsCallOptions contains the retry settings for each method of GlobalOrganizationOperationsClient.
+type GlobalOrganizationOperationsCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	List   []gax.CallOption
+}
+
+// internalGlobalOrganizationOperationsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalGlobalOrganizationOperationsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteGlobalOrganizationOperationRequest, ...gax.CallOption) (*computepb.DeleteGlobalOrganizationOperationResponse, error)
+	Get(context.Context, *computepb.GetGlobalOrganizationOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListGlobalOrganizationOperationsRequest, ...gax.CallOption) (*computepb.OperationList, error)
+}
+
+// GlobalOrganizationOperationsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The GlobalOrganizationOperations API.
+type GlobalOrganizationOperationsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalGlobalOrganizationOperationsClient
+
+	// The call options for this service.
+	CallOptions *GlobalOrganizationOperationsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *GlobalOrganizationOperationsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *GlobalOrganizationOperationsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *GlobalOrganizationOperationsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified Operations resource.
+func (c *GlobalOrganizationOperationsClient) Delete(ctx context.Context, req *computepb.DeleteGlobalOrganizationOperationRequest, opts ...gax.CallOption) (*computepb.DeleteGlobalOrganizationOperationResponse, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get retrieves the specified Operations resource. Gets a list of operations by making a list() request.
+func (c *GlobalOrganizationOperationsClient) Get(ctx context.Context, req *computepb.GetGlobalOrganizationOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of Operation resources contained within the specified organization.
+func (c *GlobalOrganizationOperationsClient) List(ctx context.Context, req *computepb.ListGlobalOrganizationOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type globalOrganizationOperationsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewGlobalOrganizationOperationsRESTClient creates a new global organization operations rest client.
+//
+// The GlobalOrganizationOperations API.
+func NewGlobalOrganizationOperationsRESTClient(ctx context.Context, opts ...option.ClientOption) (*GlobalOrganizationOperationsClient, error) {
+	clientOpts := append(defaultGlobalOrganizationOperationsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &globalOrganizationOperationsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &GlobalOrganizationOperationsClient{internalClient: c, CallOptions: &GlobalOrganizationOperationsCallOptions{}}, nil
+}
+
+func defaultGlobalOrganizationOperationsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *globalOrganizationOperationsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *globalOrganizationOperationsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *globalOrganizationOperationsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified Operations resource.
+func (c *globalOrganizationOperationsRESTClient) Delete(ctx context.Context, req *computepb.DeleteGlobalOrganizationOperationRequest, opts ...gax.CallOption) (*computepb.DeleteGlobalOrganizationOperationResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/operations/%v", req.GetOperation())
+
+	params := url.Values{}
+	if req != nil && req.ParentId != nil {
+		params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DeleteGlobalOrganizationOperationResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get retrieves the specified Operations resource. Gets a list of operations by making a list() request.
+func (c *globalOrganizationOperationsRESTClient) Get(ctx context.Context, req *computepb.GetGlobalOrganizationOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/operations/%v", req.GetOperation())
+
+	params := url.Values{}
+	if req != nil && req.ParentId != nil {
+		params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of Operation resources contained within the specified organization.
+func (c *globalOrganizationOperationsRESTClient) List(ctx context.Context, req *computepb.ListGlobalOrganizationOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/locations/global/operations")
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ParentId != nil {
+		params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.OperationList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/global_organization_operations_client_example_test.go b/compute/apiv1/global_organization_operations_client_example_test.go
new file mode 100644
index 0000000..1018ba6
--- /dev/null
+++ b/compute/apiv1/global_organization_operations_client_example_test.go
@@ -0,0 +1,93 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewGlobalOrganizationOperationsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOrganizationOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleGlobalOrganizationOperationsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOrganizationOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteGlobalOrganizationOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalOrganizationOperationsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOrganizationOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGlobalOrganizationOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalOrganizationOperationsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalOrganizationOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListGlobalOrganizationOperationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/global_public_delegated_prefixes_client.go b/compute/apiv1/global_public_delegated_prefixes_client.go
new file mode 100644
index 0000000..b0e0fc7
--- /dev/null
+++ b/compute/apiv1/global_public_delegated_prefixes_client.go
@@ -0,0 +1,438 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newGlobalPublicDelegatedPrefixesClientHook clientHook
+
+// GlobalPublicDelegatedPrefixesCallOptions contains the retry settings for each method of GlobalPublicDelegatedPrefixesClient.
+type GlobalPublicDelegatedPrefixesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+}
+
+// internalGlobalPublicDelegatedPrefixesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalGlobalPublicDelegatedPrefixesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteGlobalPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetGlobalPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.PublicDelegatedPrefix, error)
+	Insert(context.Context, *computepb.InsertGlobalPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListGlobalPublicDelegatedPrefixesRequest, ...gax.CallOption) (*computepb.PublicDelegatedPrefixList, error)
+	Patch(context.Context, *computepb.PatchGlobalPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// GlobalPublicDelegatedPrefixesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The GlobalPublicDelegatedPrefixes API.
+type GlobalPublicDelegatedPrefixesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalGlobalPublicDelegatedPrefixesClient
+
+	// The call options for this service.
+	CallOptions *GlobalPublicDelegatedPrefixesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *GlobalPublicDelegatedPrefixesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *GlobalPublicDelegatedPrefixesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *GlobalPublicDelegatedPrefixesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified global PublicDelegatedPrefix.
+func (c *GlobalPublicDelegatedPrefixesClient) Delete(ctx context.Context, req *computepb.DeleteGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified global PublicDelegatedPrefix resource.
+func (c *GlobalPublicDelegatedPrefixesClient) Get(ctx context.Context, req *computepb.GetGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefix, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a global PublicDelegatedPrefix in the specified project using the parameters that are included in the request.
+func (c *GlobalPublicDelegatedPrefixesClient) Insert(ctx context.Context, req *computepb.InsertGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists the global PublicDelegatedPrefixes for a project.
+func (c *GlobalPublicDelegatedPrefixesClient) List(ctx context.Context, req *computepb.ListGlobalPublicDelegatedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefixList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified global PublicDelegatedPrefix resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *GlobalPublicDelegatedPrefixesClient) Patch(ctx context.Context, req *computepb.PatchGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type globalPublicDelegatedPrefixesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewGlobalPublicDelegatedPrefixesRESTClient creates a new global public delegated prefixes rest client.
+//
+// The GlobalPublicDelegatedPrefixes API.
+func NewGlobalPublicDelegatedPrefixesRESTClient(ctx context.Context, opts ...option.ClientOption) (*GlobalPublicDelegatedPrefixesClient, error) {
+	clientOpts := append(defaultGlobalPublicDelegatedPrefixesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &globalPublicDelegatedPrefixesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &GlobalPublicDelegatedPrefixesClient{internalClient: c, CallOptions: &GlobalPublicDelegatedPrefixesCallOptions{}}, nil
+}
+
+func defaultGlobalPublicDelegatedPrefixesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *globalPublicDelegatedPrefixesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *globalPublicDelegatedPrefixesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *globalPublicDelegatedPrefixesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified global PublicDelegatedPrefix.
+func (c *globalPublicDelegatedPrefixesRESTClient) Delete(ctx context.Context, req *computepb.DeleteGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicDelegatedPrefixes/%v", req.GetProject(), req.GetPublicDelegatedPrefix())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified global PublicDelegatedPrefix resource.
+func (c *globalPublicDelegatedPrefixesRESTClient) Get(ctx context.Context, req *computepb.GetGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefix, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicDelegatedPrefixes/%v", req.GetProject(), req.GetPublicDelegatedPrefix())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicDelegatedPrefix{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a global PublicDelegatedPrefix in the specified project using the parameters that are included in the request.
+func (c *globalPublicDelegatedPrefixesRESTClient) Insert(ctx context.Context, req *computepb.InsertGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPublicDelegatedPrefixResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicDelegatedPrefixes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists the global PublicDelegatedPrefixes for a project.
+func (c *globalPublicDelegatedPrefixesRESTClient) List(ctx context.Context, req *computepb.ListGlobalPublicDelegatedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefixList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicDelegatedPrefixes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicDelegatedPrefixList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified global PublicDelegatedPrefix resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *globalPublicDelegatedPrefixesRESTClient) Patch(ctx context.Context, req *computepb.PatchGlobalPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPublicDelegatedPrefixResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicDelegatedPrefixes/%v", req.GetProject(), req.GetPublicDelegatedPrefix())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/global_public_delegated_prefixes_client_example_test.go b/compute/apiv1/global_public_delegated_prefixes_client_example_test.go
new file mode 100644
index 0000000..dc9f1da
--- /dev/null
+++ b/compute/apiv1/global_public_delegated_prefixes_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewGlobalPublicDelegatedPrefixesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleGlobalPublicDelegatedPrefixesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteGlobalPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalPublicDelegatedPrefixesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGlobalPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalPublicDelegatedPrefixesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertGlobalPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalPublicDelegatedPrefixesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListGlobalPublicDelegatedPrefixesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleGlobalPublicDelegatedPrefixesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewGlobalPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchGlobalPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/health_checks_client.go b/compute/apiv1/health_checks_client.go
new file mode 100644
index 0000000..887b7c4
--- /dev/null
+++ b/compute/apiv1/health_checks_client.go
@@ -0,0 +1,574 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newHealthChecksClientHook clientHook
+
+// HealthChecksCallOptions contains the retry settings for each method of HealthChecksClient.
+type HealthChecksCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+	Update         []gax.CallOption
+}
+
+// internalHealthChecksClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalHealthChecksClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListHealthChecksRequest, ...gax.CallOption) (*computepb.HealthChecksAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetHealthCheckRequest, ...gax.CallOption) (*computepb.HealthCheck, error)
+	Insert(context.Context, *computepb.InsertHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListHealthChecksRequest, ...gax.CallOption) (*computepb.HealthCheckList, error)
+	Patch(context.Context, *computepb.PatchHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// HealthChecksClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The HealthChecks API.
+type HealthChecksClient struct {
+	// The internal transport-dependent client.
+	internalClient internalHealthChecksClient
+
+	// The call options for this service.
+	CallOptions *HealthChecksCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *HealthChecksClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *HealthChecksClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *HealthChecksClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves the list of all HealthCheck resources, regional and global, available to the specified project.
+func (c *HealthChecksClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListHealthChecksRequest, opts ...gax.CallOption) (*computepb.HealthChecksAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified HealthCheck resource.
+func (c *HealthChecksClient) Delete(ctx context.Context, req *computepb.DeleteHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified HealthCheck resource. Gets a list of available health checks by making a list() request.
+func (c *HealthChecksClient) Get(ctx context.Context, req *computepb.GetHealthCheckRequest, opts ...gax.CallOption) (*computepb.HealthCheck, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a HealthCheck resource in the specified project using the data included in the request.
+func (c *HealthChecksClient) Insert(ctx context.Context, req *computepb.InsertHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of HealthCheck resources available to the specified project.
+func (c *HealthChecksClient) List(ctx context.Context, req *computepb.ListHealthChecksRequest, opts ...gax.CallOption) (*computepb.HealthCheckList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates a HealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *HealthChecksClient) Patch(ctx context.Context, req *computepb.PatchHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates a HealthCheck resource in the specified project using the data included in the request.
+func (c *HealthChecksClient) Update(ctx context.Context, req *computepb.UpdateHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type healthChecksRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewHealthChecksRESTClient creates a new health checks rest client.
+//
+// The HealthChecks API.
+func NewHealthChecksRESTClient(ctx context.Context, opts ...option.ClientOption) (*HealthChecksClient, error) {
+	clientOpts := append(defaultHealthChecksRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &healthChecksRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &HealthChecksClient{internalClient: c, CallOptions: &HealthChecksCallOptions{}}, nil
+}
+
+func defaultHealthChecksRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *healthChecksRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *healthChecksRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *healthChecksRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves the list of all HealthCheck resources, regional and global, available to the specified project.
+func (c *healthChecksRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListHealthChecksRequest, opts ...gax.CallOption) (*computepb.HealthChecksAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/healthChecks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthChecksAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified HealthCheck resource.
+func (c *healthChecksRESTClient) Delete(ctx context.Context, req *computepb.DeleteHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/healthChecks/%v", req.GetProject(), req.GetHealthCheck())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified HealthCheck resource. Gets a list of available health checks by making a list() request.
+func (c *healthChecksRESTClient) Get(ctx context.Context, req *computepb.GetHealthCheckRequest, opts ...gax.CallOption) (*computepb.HealthCheck, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/healthChecks/%v", req.GetProject(), req.GetHealthCheck())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthCheck{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a HealthCheck resource in the specified project using the data included in the request.
+func (c *healthChecksRESTClient) Insert(ctx context.Context, req *computepb.InsertHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/healthChecks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of HealthCheck resources available to the specified project.
+func (c *healthChecksRESTClient) List(ctx context.Context, req *computepb.ListHealthChecksRequest, opts ...gax.CallOption) (*computepb.HealthCheckList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/healthChecks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthCheckList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates a HealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *healthChecksRESTClient) Patch(ctx context.Context, req *computepb.PatchHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/healthChecks/%v", req.GetProject(), req.GetHealthCheck())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates a HealthCheck resource in the specified project using the data included in the request.
+func (c *healthChecksRESTClient) Update(ctx context.Context, req *computepb.UpdateHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetHealthCheck() != "" {
+		params.Add("healthCheck", fmt.Sprintf("%v", req.GetHealthCheck()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/health_checks_client_example_test.go b/compute/apiv1/health_checks_client_example_test.go
new file mode 100644
index 0000000..fe6aeb7
--- /dev/null
+++ b/compute/apiv1/health_checks_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewHealthChecksRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleHealthChecksClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListHealthChecksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleHealthChecksClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleHealthChecksClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleHealthChecksClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleHealthChecksClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListHealthChecksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleHealthChecksClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleHealthChecksClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/images_client.go b/compute/apiv1/images_client.go
new file mode 100644
index 0000000..8fbfa02
--- /dev/null
+++ b/compute/apiv1/images_client.go
@@ -0,0 +1,763 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newImagesClientHook clientHook
+
+// ImagesCallOptions contains the retry settings for each method of ImagesClient.
+type ImagesCallOptions struct {
+	Delete             []gax.CallOption
+	Deprecate          []gax.CallOption
+	Get                []gax.CallOption
+	GetFromFamily      []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	Patch              []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	SetLabels          []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalImagesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalImagesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteImageRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Deprecate(context.Context, *computepb.DeprecateImageRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetImageRequest, ...gax.CallOption) (*computepb.Image, error)
+	GetFromFamily(context.Context, *computepb.GetFromFamilyImageRequest, ...gax.CallOption) (*computepb.Image, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyImageRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertImageRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListImagesRequest, ...gax.CallOption) (*computepb.ImageList, error)
+	Patch(context.Context, *computepb.PatchImageRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyImageRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetLabels(context.Context, *computepb.SetLabelsImageRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsImageRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// ImagesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Images API.
+type ImagesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalImagesClient
+
+	// The call options for this service.
+	CallOptions *ImagesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ImagesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ImagesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ImagesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified image.
+func (c *ImagesClient) Delete(ctx context.Context, req *computepb.DeleteImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Deprecate sets the deprecation status of an image.
+//
+// If an empty request body is given, clears the deprecation status instead.
+func (c *ImagesClient) Deprecate(ctx context.Context, req *computepb.DeprecateImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Deprecate(ctx, req, opts...)
+}
+
+// Get returns the specified image. Gets a list of available images by making a list() request.
+func (c *ImagesClient) Get(ctx context.Context, req *computepb.GetImageRequest, opts ...gax.CallOption) (*computepb.Image, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetFromFamily returns the latest image that is part of an image family and is not deprecated.
+func (c *ImagesClient) GetFromFamily(ctx context.Context, req *computepb.GetFromFamilyImageRequest, opts ...gax.CallOption) (*computepb.Image, error) {
+	return c.internalClient.GetFromFamily(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *ImagesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyImageRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates an image in the specified project using the data included in the request.
+func (c *ImagesClient) Insert(ctx context.Context, req *computepb.InsertImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of custom images available to the specified project. Custom images are images you create that belong to your project. This method does not get any images that belong to other projects, including publicly-available images, like Debian 8. If you want to get a list of publicly-available images, use this method to make a request to the respective image project, such as debian-cloud or windows-cloud.
+func (c *ImagesClient) List(ctx context.Context, req *computepb.ListImagesRequest, opts ...gax.CallOption) (*computepb.ImageList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified image with the data included in the request. Only the following fields can be modified: family, description, deprecation status.
+func (c *ImagesClient) Patch(ctx context.Context, req *computepb.PatchImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *ImagesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyImageRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on an image. To learn more about labels, read the Labeling Resources documentation.
+func (c *ImagesClient) SetLabels(ctx context.Context, req *computepb.SetLabelsImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *ImagesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsImageRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type imagesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewImagesRESTClient creates a new images rest client.
+//
+// The Images API.
+func NewImagesRESTClient(ctx context.Context, opts ...option.ClientOption) (*ImagesClient, error) {
+	clientOpts := append(defaultImagesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &imagesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ImagesClient{internalClient: c, CallOptions: &ImagesCallOptions{}}, nil
+}
+
+func defaultImagesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *imagesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *imagesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *imagesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified image.
+func (c *imagesRESTClient) Delete(ctx context.Context, req *computepb.DeleteImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v", req.GetProject(), req.GetImage())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Deprecate sets the deprecation status of an image.
+//
+// If an empty request body is given, clears the deprecation status instead.
+func (c *imagesRESTClient) Deprecate(ctx context.Context, req *computepb.DeprecateImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDeprecationStatusResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v/deprecate", req.GetProject(), req.GetImage())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified image. Gets a list of available images by making a list() request.
+func (c *imagesRESTClient) Get(ctx context.Context, req *computepb.GetImageRequest, opts ...gax.CallOption) (*computepb.Image, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v", req.GetProject(), req.GetImage())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Image{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetFromFamily returns the latest image that is part of an image family and is not deprecated.
+func (c *imagesRESTClient) GetFromFamily(ctx context.Context, req *computepb.GetFromFamilyImageRequest, opts ...gax.CallOption) (*computepb.Image, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/family/%v", req.GetProject(), req.GetFamily())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Image{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *imagesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyImageRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v/getIamPolicy", req.GetProject(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an image in the specified project using the data included in the request.
+func (c *imagesRESTClient) Insert(ctx context.Context, req *computepb.InsertImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetImageResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.ForceCreate != nil {
+		params.Add("forceCreate", fmt.Sprintf("%v", req.GetForceCreate()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of custom images available to the specified project. Custom images are images you create that belong to your project. This method does not get any images that belong to other projects, including publicly-available images, like Debian 8. If you want to get a list of publicly-available images, use this method to make a request to the respective image project, such as debian-cloud or windows-cloud.
+func (c *imagesRESTClient) List(ctx context.Context, req *computepb.ListImagesRequest, opts ...gax.CallOption) (*computepb.ImageList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ImageList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified image with the data included in the request. Only the following fields can be modified: family, description, deprecation status.
+func (c *imagesRESTClient) Patch(ctx context.Context, req *computepb.PatchImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetImageResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v", req.GetProject(), req.GetImage())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *imagesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyImageRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v/setIamPolicy", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on an image. To learn more about labels, read the Labeling Resources documentation.
+func (c *imagesRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsImageRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v/setLabels", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *imagesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsImageRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/images/%v/testIamPermissions", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/images_client_example_test.go b/compute/apiv1/images_client_example_test.go
new file mode 100644
index 0000000..30c3815
--- /dev/null
+++ b/compute/apiv1/images_client_example_test.go
@@ -0,0 +1,245 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewImagesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleImagesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_Deprecate() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeprecateImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Deprecate(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_GetFromFamily() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetFromFamilyImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetFromFamily(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListImagesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleImagesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewImagesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsImageRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/instance_group_managers_client.go b/compute/apiv1/instance_group_managers_client.go
new file mode 100644
index 0000000..6303952
--- /dev/null
+++ b/compute/apiv1/instance_group_managers_client.go
@@ -0,0 +1,1387 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInstanceGroupManagersClientHook clientHook
+
+// InstanceGroupManagersCallOptions contains the retry settings for each method of InstanceGroupManagersClient.
+type InstanceGroupManagersCallOptions struct {
+	AbandonInstances         []gax.CallOption
+	AggregatedList           []gax.CallOption
+	ApplyUpdatesToInstances  []gax.CallOption
+	CreateInstances          []gax.CallOption
+	Delete                   []gax.CallOption
+	DeleteInstances          []gax.CallOption
+	DeletePerInstanceConfigs []gax.CallOption
+	Get                      []gax.CallOption
+	Insert                   []gax.CallOption
+	List                     []gax.CallOption
+	ListErrors               []gax.CallOption
+	ListManagedInstances     []gax.CallOption
+	ListPerInstanceConfigs   []gax.CallOption
+	Patch                    []gax.CallOption
+	PatchPerInstanceConfigs  []gax.CallOption
+	RecreateInstances        []gax.CallOption
+	Resize                   []gax.CallOption
+	SetInstanceTemplate      []gax.CallOption
+	SetTargetPools           []gax.CallOption
+	UpdatePerInstanceConfigs []gax.CallOption
+}
+
+// internalInstanceGroupManagersClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInstanceGroupManagersClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AbandonInstances(context.Context, *computepb.AbandonInstancesInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.InstanceGroupManagerAggregatedList, error)
+	ApplyUpdatesToInstances(context.Context, *computepb.ApplyUpdatesToInstancesInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	CreateInstances(context.Context, *computepb.CreateInstancesInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeleteInstances(context.Context, *computepb.DeleteInstancesInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeletePerInstanceConfigs(context.Context, *computepb.DeletePerInstanceConfigsInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.InstanceGroupManager, error)
+	Insert(context.Context, *computepb.InsertInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.InstanceGroupManagerList, error)
+	ListErrors(context.Context, *computepb.ListErrorsInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.InstanceGroupManagersListErrorsResponse, error)
+	ListManagedInstances(context.Context, *computepb.ListManagedInstancesInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.InstanceGroupManagersListManagedInstancesResponse, error)
+	ListPerInstanceConfigs(context.Context, *computepb.ListPerInstanceConfigsInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.InstanceGroupManagersListPerInstanceConfigsResp, error)
+	Patch(context.Context, *computepb.PatchInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	PatchPerInstanceConfigs(context.Context, *computepb.PatchPerInstanceConfigsInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RecreateInstances(context.Context, *computepb.RecreateInstancesInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Resize(context.Context, *computepb.ResizeInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetInstanceTemplate(context.Context, *computepb.SetInstanceTemplateInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetTargetPools(context.Context, *computepb.SetTargetPoolsInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdatePerInstanceConfigs(context.Context, *computepb.UpdatePerInstanceConfigsInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// InstanceGroupManagersClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The InstanceGroupManagers API.
+type InstanceGroupManagersClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInstanceGroupManagersClient
+
+	// The call options for this service.
+	CallOptions *InstanceGroupManagersCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InstanceGroupManagersClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InstanceGroupManagersClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InstanceGroupManagersClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AbandonInstances flags the specified instances to be removed from the managed instance group. Abandoning an instance does not delete the instance, but it does remove the instance from any target pools that are applied by the managed instance group. This method reduces the targetSize of the managed instance group by the number of instances that you abandon. This operation is marked as DONE when the action is scheduled even if the instances have not yet been removed from the group. You must separately verify the status of the abandoning action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *InstanceGroupManagersClient) AbandonInstances(ctx context.Context, req *computepb.AbandonInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AbandonInstances(ctx, req, opts...)
+}
+
+// AggregatedList retrieves the list of managed instance groups and groups them by zone.
+func (c *InstanceGroupManagersClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagerAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// ApplyUpdatesToInstances applies changes to selected instances on the managed instance group. This method can be used to apply new overrides and/or new versions.
+func (c *InstanceGroupManagersClient) ApplyUpdatesToInstances(ctx context.Context, req *computepb.ApplyUpdatesToInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.ApplyUpdatesToInstances(ctx, req, opts...)
+}
+
+// CreateInstances creates instances with per-instance configs in this managed instance group. Instances are created using the current instance template. The create instances operation is marked DONE if the createInstances request is successful. The underlying actions take additional time. You must separately verify the status of the creating or actions with the listmanagedinstances method.
+func (c *InstanceGroupManagersClient) CreateInstances(ctx context.Context, req *computepb.CreateInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.CreateInstances(ctx, req, opts...)
+}
+
+// Delete deletes the specified managed instance group and all of the instances in that group. Note that the instance group must not belong to a backend service. Read  Deleting an instance group for more information.
+func (c *InstanceGroupManagersClient) Delete(ctx context.Context, req *computepb.DeleteInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DeleteInstances flags the specified instances in the managed instance group for immediate deletion. The instances are also removed from any target pools of which they were a member. This method reduces the targetSize of the managed instance group by the number of instances that you delete. This operation is marked as DONE when the action is scheduled even if the instances are still being deleted. You must separately verify the status of the deleting action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *InstanceGroupManagersClient) DeleteInstances(ctx context.Context, req *computepb.DeleteInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeleteInstances(ctx, req, opts...)
+}
+
+// DeletePerInstanceConfigs deletes selected per-instance configs for the managed instance group.
+func (c *InstanceGroupManagersClient) DeletePerInstanceConfigs(ctx context.Context, req *computepb.DeletePerInstanceConfigsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeletePerInstanceConfigs(ctx, req, opts...)
+}
+
+// Get returns all of the details about the specified managed instance group. Gets a list of available managed instance groups by making a list() request.
+func (c *InstanceGroupManagersClient) Get(ctx context.Context, req *computepb.GetInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManager, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a managed instance group using the information that you specify in the request. After the group is created, instances in the group are created using the specified instance template. This operation is marked as DONE when the group is created even if the instances in the group have not yet been created. You must separately verify the status of the individual instances with the listmanagedinstances method.
+//
+// A managed instance group can have up to 1000 VM instances per group. Please contact Cloud Support if you need an increase in this limit.
+func (c *InstanceGroupManagersClient) Insert(ctx context.Context, req *computepb.InsertInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of managed instance groups that are contained within the specified project and zone.
+func (c *InstanceGroupManagersClient) List(ctx context.Context, req *computepb.ListInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagerList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListErrors lists all errors thrown by actions on instances for a given managed instance group. The filter and orderBy query parameters are not supported.
+func (c *InstanceGroupManagersClient) ListErrors(ctx context.Context, req *computepb.ListErrorsInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagersListErrorsResponse, error) {
+	return c.internalClient.ListErrors(ctx, req, opts...)
+}
+
+// ListManagedInstances lists all of the instances in the managed instance group. Each instance in the list has a currentAction, which indicates the action that the managed instance group is performing on the instance. For example, if the group is still creating an instance, the currentAction is CREATING. If a previous action failed, the list displays the errors for that failed action. The orderBy query parameter is not supported.
+func (c *InstanceGroupManagersClient) ListManagedInstances(ctx context.Context, req *computepb.ListManagedInstancesInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagersListManagedInstancesResponse, error) {
+	return c.internalClient.ListManagedInstances(ctx, req, opts...)
+}
+
+// ListPerInstanceConfigs lists all of the per-instance configs defined for the managed instance group. The orderBy query parameter is not supported.
+func (c *InstanceGroupManagersClient) ListPerInstanceConfigs(ctx context.Context, req *computepb.ListPerInstanceConfigsInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagersListPerInstanceConfigsResp, error) {
+	return c.internalClient.ListPerInstanceConfigs(ctx, req, opts...)
+}
+
+// Patch updates a managed instance group using the information that you specify in the request. This operation is marked as DONE when the group is patched even if the instances in the group are still in the process of being patched. You must separately verify the status of the individual instances with the listManagedInstances method. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InstanceGroupManagersClient) Patch(ctx context.Context, req *computepb.PatchInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// PatchPerInstanceConfigs inserts or patches per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *InstanceGroupManagersClient) PatchPerInstanceConfigs(ctx context.Context, req *computepb.PatchPerInstanceConfigsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.PatchPerInstanceConfigs(ctx, req, opts...)
+}
+
+// RecreateInstances flags the specified VM instances in the managed instance group to be immediately recreated. Each instance is recreated using the group’s current configuration. This operation is marked as DONE when the flag is set even if the instances have not yet been recreated. You must separately verify the status of each instance by checking its currentAction field; for more information, see Checking the status of managed instances.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *InstanceGroupManagersClient) RecreateInstances(ctx context.Context, req *computepb.RecreateInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RecreateInstances(ctx, req, opts...)
+}
+
+// Resize resizes the managed instance group. If you increase the size, the group creates new instances using the current instance template. If you decrease the size, the group deletes instances. The resize operation is marked DONE when the resize actions are scheduled even if the group has not yet added or deleted any instances. You must separately verify the status of the creating or deleting actions with the listmanagedinstances method.
+//
+// When resizing down, the instance group arbitrarily chooses the order in which VMs are deleted. The group takes into account some VM attributes when making the selection including:
+//
+//   The status of the VM instance. + The health of the VM instance. + The instance template version the VM is based on. + For regional managed instance groups, the location of the VM instance.
+//
+// This list is subject to change.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+func (c *InstanceGroupManagersClient) Resize(ctx context.Context, req *computepb.ResizeInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Resize(ctx, req, opts...)
+}
+
+// SetInstanceTemplate specifies the instance template to use when creating new instances in this group. The templates for existing instances in the group do not change unless you run recreateInstances, run applyUpdatesToInstances, or set the group’s updatePolicy.type to PROACTIVE.
+func (c *InstanceGroupManagersClient) SetInstanceTemplate(ctx context.Context, req *computepb.SetInstanceTemplateInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetInstanceTemplate(ctx, req, opts...)
+}
+
+// SetTargetPools modifies the target pools to which all instances in this managed instance group are assigned. The target pools automatically apply to all of the instances in the managed instance group. This operation is marked DONE when you make the request even if the instances have not yet been added to their target pools. The change might take some time to apply to all of the instances in the group depending on the size of the group.
+func (c *InstanceGroupManagersClient) SetTargetPools(ctx context.Context, req *computepb.SetTargetPoolsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetTargetPools(ctx, req, opts...)
+}
+
+// UpdatePerInstanceConfigs inserts or updates per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *InstanceGroupManagersClient) UpdatePerInstanceConfigs(ctx context.Context, req *computepb.UpdatePerInstanceConfigsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdatePerInstanceConfigs(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type instanceGroupManagersRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInstanceGroupManagersRESTClient creates a new instance group managers rest client.
+//
+// The InstanceGroupManagers API.
+func NewInstanceGroupManagersRESTClient(ctx context.Context, opts ...option.ClientOption) (*InstanceGroupManagersClient, error) {
+	clientOpts := append(defaultInstanceGroupManagersRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &instanceGroupManagersRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InstanceGroupManagersClient{internalClient: c, CallOptions: &InstanceGroupManagersCallOptions{}}, nil
+}
+
+func defaultInstanceGroupManagersRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *instanceGroupManagersRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *instanceGroupManagersRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *instanceGroupManagersRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AbandonInstances flags the specified instances to be removed from the managed instance group. Abandoning an instance does not delete the instance, but it does remove the instance from any target pools that are applied by the managed instance group. This method reduces the targetSize of the managed instance group by the number of instances that you abandon. This operation is marked as DONE when the action is scheduled even if the instances have not yet been removed from the group. You must separately verify the status of the abandoning action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *instanceGroupManagersRESTClient) AbandonInstances(ctx context.Context, req *computepb.AbandonInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersAbandonInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/abandonInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves the list of managed instance groups and groups them by zone.
+func (c *instanceGroupManagersRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagerAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/instanceGroupManagers", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManagerAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ApplyUpdatesToInstances applies changes to selected instances on the managed instance group. This method can be used to apply new overrides and/or new versions.
+func (c *instanceGroupManagersRESTClient) ApplyUpdatesToInstances(ctx context.Context, req *computepb.ApplyUpdatesToInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersApplyUpdatesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/applyUpdatesToInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// CreateInstances creates instances with per-instance configs in this managed instance group. Instances are created using the current instance template. The create instances operation is marked DONE if the createInstances request is successful. The underlying actions take additional time. You must separately verify the status of the creating or actions with the listmanagedinstances method.
+func (c *instanceGroupManagersRESTClient) CreateInstances(ctx context.Context, req *computepb.CreateInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersCreateInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/createInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified managed instance group and all of the instances in that group. Note that the instance group must not belong to a backend service. Read  Deleting an instance group for more information.
+func (c *instanceGroupManagersRESTClient) Delete(ctx context.Context, req *computepb.DeleteInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeleteInstances flags the specified instances in the managed instance group for immediate deletion. The instances are also removed from any target pools of which they were a member. This method reduces the targetSize of the managed instance group by the number of instances that you delete. This operation is marked as DONE when the action is scheduled even if the instances are still being deleted. You must separately verify the status of the deleting action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *instanceGroupManagersRESTClient) DeleteInstances(ctx context.Context, req *computepb.DeleteInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersDeleteInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/deleteInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeletePerInstanceConfigs deletes selected per-instance configs for the managed instance group.
+func (c *instanceGroupManagersRESTClient) DeletePerInstanceConfigs(ctx context.Context, req *computepb.DeletePerInstanceConfigsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersDeletePerInstanceConfigsReqResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/deletePerInstanceConfigs", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns all of the details about the specified managed instance group. Gets a list of available managed instance groups by making a list() request.
+func (c *instanceGroupManagersRESTClient) Get(ctx context.Context, req *computepb.GetInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManager, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManager{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a managed instance group using the information that you specify in the request. After the group is created, instances in the group are created using the specified instance template. This operation is marked as DONE when the group is created even if the instances in the group have not yet been created. You must separately verify the status of the individual instances with the listmanagedinstances method.
+//
+// A managed instance group can have up to 1000 VM instances per group. Please contact Cloud Support if you need an increase in this limit.
+func (c *instanceGroupManagersRESTClient) Insert(ctx context.Context, req *computepb.InsertInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of managed instance groups that are contained within the specified project and zone.
+func (c *instanceGroupManagersRESTClient) List(ctx context.Context, req *computepb.ListInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagerList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManagerList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListErrors lists all errors thrown by actions on instances for a given managed instance group. The filter and orderBy query parameters are not supported.
+func (c *instanceGroupManagersRESTClient) ListErrors(ctx context.Context, req *computepb.ListErrorsInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagersListErrorsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/listErrors", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManagersListErrorsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListManagedInstances lists all of the instances in the managed instance group. Each instance in the list has a currentAction, which indicates the action that the managed instance group is performing on the instance. For example, if the group is still creating an instance, the currentAction is CREATING. If a previous action failed, the list displays the errors for that failed action. The orderBy query parameter is not supported.
+func (c *instanceGroupManagersRESTClient) ListManagedInstances(ctx context.Context, req *computepb.ListManagedInstancesInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagersListManagedInstancesResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/listManagedInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManagersListManagedInstancesResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListPerInstanceConfigs lists all of the per-instance configs defined for the managed instance group. The orderBy query parameter is not supported.
+func (c *instanceGroupManagersRESTClient) ListPerInstanceConfigs(ctx context.Context, req *computepb.ListPerInstanceConfigsInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManagersListPerInstanceConfigsResp, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/listPerInstanceConfigs", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManagersListPerInstanceConfigsResp{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates a managed instance group using the information that you specify in the request. This operation is marked as DONE when the group is patched even if the instances in the group are still in the process of being patched. You must separately verify the status of the individual instances with the listManagedInstances method. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *instanceGroupManagersRESTClient) Patch(ctx context.Context, req *computepb.PatchInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// PatchPerInstanceConfigs inserts or patches per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *instanceGroupManagersRESTClient) PatchPerInstanceConfigs(ctx context.Context, req *computepb.PatchPerInstanceConfigsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersPatchPerInstanceConfigsReqResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/patchPerInstanceConfigs", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RecreateInstances flags the specified VM instances in the managed instance group to be immediately recreated. Each instance is recreated using the group’s current configuration. This operation is marked as DONE when the flag is set even if the instances have not yet been recreated. You must separately verify the status of each instance by checking its currentAction field; for more information, see Checking the status of managed instances.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *instanceGroupManagersRESTClient) RecreateInstances(ctx context.Context, req *computepb.RecreateInstancesInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersRecreateInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/recreateInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Resize resizes the managed instance group. If you increase the size, the group creates new instances using the current instance template. If you decrease the size, the group deletes instances. The resize operation is marked DONE when the resize actions are scheduled even if the group has not yet added or deleted any instances. You must separately verify the status of the creating or deleting actions with the listmanagedinstances method.
+//
+// When resizing down, the instance group arbitrarily chooses the order in which VMs are deleted. The group takes into account some VM attributes when making the selection including:
+//
+//   The status of the VM instance. + The health of the VM instance. + The instance template version the VM is based on. + For regional managed instance groups, the location of the VM instance.
+//
+// This list is subject to change.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+func (c *instanceGroupManagersRESTClient) Resize(ctx context.Context, req *computepb.ResizeInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/resize", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetSize() != 0 {
+		params.Add("size", fmt.Sprintf("%v", req.GetSize()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetInstanceTemplate specifies the instance template to use when creating new instances in this group. The templates for existing instances in the group do not change unless you run recreateInstances, run applyUpdatesToInstances, or set the group’s updatePolicy.type to PROACTIVE.
+func (c *instanceGroupManagersRESTClient) SetInstanceTemplate(ctx context.Context, req *computepb.SetInstanceTemplateInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersSetInstanceTemplateRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/setInstanceTemplate", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetTargetPools modifies the target pools to which all instances in this managed instance group are assigned. The target pools automatically apply to all of the instances in the managed instance group. This operation is marked DONE when you make the request even if the instances have not yet been added to their target pools. The change might take some time to apply to all of the instances in the group depending on the size of the group.
+func (c *instanceGroupManagersRESTClient) SetTargetPools(ctx context.Context, req *computepb.SetTargetPoolsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersSetTargetPoolsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/setTargetPools", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdatePerInstanceConfigs inserts or updates per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *instanceGroupManagersRESTClient) UpdatePerInstanceConfigs(ctx context.Context, req *computepb.UpdatePerInstanceConfigsInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagersUpdatePerInstanceConfigsReqResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroupManagers/%v/updatePerInstanceConfigs", req.GetProject(), req.GetZone(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/instance_group_managers_client_example_test.go b/compute/apiv1/instance_group_managers_client_example_test.go
new file mode 100644
index 0000000..d5602e7
--- /dev/null
+++ b/compute/apiv1/instance_group_managers_client_example_test.go
@@ -0,0 +1,416 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInstanceGroupManagersRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInstanceGroupManagersClient_AbandonInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AbandonInstancesInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AbandonInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_ApplyUpdatesToInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ApplyUpdatesToInstancesInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ApplyUpdatesToInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_CreateInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.CreateInstancesInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.CreateInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_DeleteInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInstancesInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeleteInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_DeletePerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeletePerInstanceConfigsInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeletePerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_ListErrors() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListErrorsInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListErrors(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_ListManagedInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListManagedInstancesInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListManagedInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_ListPerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPerInstanceConfigsInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListPerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_PatchPerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchPerInstanceConfigsInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.PatchPerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_RecreateInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RecreateInstancesInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RecreateInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_Resize() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ResizeInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Resize(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_SetInstanceTemplate() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetInstanceTemplateInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetInstanceTemplate(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_SetTargetPools() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetTargetPoolsInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetTargetPools(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupManagersClient_UpdatePerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdatePerInstanceConfigsInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdatePerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/instance_groups_client.go b/compute/apiv1/instance_groups_client.go
new file mode 100644
index 0000000..0d57cd3
--- /dev/null
+++ b/compute/apiv1/instance_groups_client.go
@@ -0,0 +1,708 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInstanceGroupsClientHook clientHook
+
+// InstanceGroupsCallOptions contains the retry settings for each method of InstanceGroupsClient.
+type InstanceGroupsCallOptions struct {
+	AddInstances    []gax.CallOption
+	AggregatedList  []gax.CallOption
+	Delete          []gax.CallOption
+	Get             []gax.CallOption
+	Insert          []gax.CallOption
+	List            []gax.CallOption
+	ListInstances   []gax.CallOption
+	RemoveInstances []gax.CallOption
+	SetNamedPorts   []gax.CallOption
+}
+
+// internalInstanceGroupsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInstanceGroupsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddInstances(context.Context, *computepb.AddInstancesInstanceGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListInstanceGroupsRequest, ...gax.CallOption) (*computepb.InstanceGroupAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteInstanceGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetInstanceGroupRequest, ...gax.CallOption) (*computepb.InstanceGroup, error)
+	Insert(context.Context, *computepb.InsertInstanceGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListInstanceGroupsRequest, ...gax.CallOption) (*computepb.InstanceGroupList, error)
+	ListInstances(context.Context, *computepb.ListInstancesInstanceGroupsRequest, ...gax.CallOption) (*computepb.InstanceGroupsListInstances, error)
+	RemoveInstances(context.Context, *computepb.RemoveInstancesInstanceGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetNamedPorts(context.Context, *computepb.SetNamedPortsInstanceGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// InstanceGroupsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The InstanceGroups API.
+type InstanceGroupsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInstanceGroupsClient
+
+	// The call options for this service.
+	CallOptions *InstanceGroupsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InstanceGroupsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InstanceGroupsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InstanceGroupsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddInstances adds a list of instances to the specified instance group. All of the instances in the instance group must be in the same network/subnetwork. Read  Adding instances for more information.
+func (c *InstanceGroupsClient) AddInstances(ctx context.Context, req *computepb.AddInstancesInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddInstances(ctx, req, opts...)
+}
+
+// AggregatedList retrieves the list of instance groups and sorts them by zone.
+func (c *InstanceGroupsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.InstanceGroupAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified instance group. The instances in the group are not deleted. Note that instance group must not belong to a backend service. Read  Deleting an instance group for more information.
+func (c *InstanceGroupsClient) Delete(ctx context.Context, req *computepb.DeleteInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified zonal instance group. Get a list of available zonal instance groups by making a list() request.
+//
+// For managed instance groups, use the instanceGroupManagers or regionInstanceGroupManagers methods instead.
+func (c *InstanceGroupsClient) Get(ctx context.Context, req *computepb.GetInstanceGroupRequest, opts ...gax.CallOption) (*computepb.InstanceGroup, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates an instance group in the specified project using the parameters that are included in the request.
+func (c *InstanceGroupsClient) Insert(ctx context.Context, req *computepb.InsertInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of zonal instance group resources contained within the specified zone.
+//
+// For managed instance groups, use the instanceGroupManagers or regionInstanceGroupManagers methods instead.
+func (c *InstanceGroupsClient) List(ctx context.Context, req *computepb.ListInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.InstanceGroupList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListInstances lists the instances in the specified instance group. The orderBy query parameter is not supported.
+func (c *InstanceGroupsClient) ListInstances(ctx context.Context, req *computepb.ListInstancesInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.InstanceGroupsListInstances, error) {
+	return c.internalClient.ListInstances(ctx, req, opts...)
+}
+
+// RemoveInstances removes one or more instances from the specified instance group, but does not delete those instances.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration before the VM instance is removed or deleted.
+func (c *InstanceGroupsClient) RemoveInstances(ctx context.Context, req *computepb.RemoveInstancesInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveInstances(ctx, req, opts...)
+}
+
+// SetNamedPorts sets the named ports for the specified instance group.
+func (c *InstanceGroupsClient) SetNamedPorts(ctx context.Context, req *computepb.SetNamedPortsInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetNamedPorts(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type instanceGroupsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInstanceGroupsRESTClient creates a new instance groups rest client.
+//
+// The InstanceGroups API.
+func NewInstanceGroupsRESTClient(ctx context.Context, opts ...option.ClientOption) (*InstanceGroupsClient, error) {
+	clientOpts := append(defaultInstanceGroupsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &instanceGroupsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InstanceGroupsClient{internalClient: c, CallOptions: &InstanceGroupsCallOptions{}}, nil
+}
+
+func defaultInstanceGroupsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *instanceGroupsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *instanceGroupsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *instanceGroupsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddInstances adds a list of instances to the specified instance group. All of the instances in the instance group must be in the same network/subnetwork. Read  Adding instances for more information.
+func (c *instanceGroupsRESTClient) AddInstances(ctx context.Context, req *computepb.AddInstancesInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupsAddInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups/%v/addInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves the list of instance groups and sorts them by zone.
+func (c *instanceGroupsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.InstanceGroupAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/instanceGroups", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified instance group. The instances in the group are not deleted. Note that instance group must not belong to a backend service. Read  Deleting an instance group for more information.
+func (c *instanceGroupsRESTClient) Delete(ctx context.Context, req *computepb.DeleteInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups/%v", req.GetProject(), req.GetZone(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified zonal instance group. Get a list of available zonal instance groups by making a list() request.
+//
+// For managed instance groups, use the instanceGroupManagers or regionInstanceGroupManagers methods instead.
+func (c *instanceGroupsRESTClient) Get(ctx context.Context, req *computepb.GetInstanceGroupRequest, opts ...gax.CallOption) (*computepb.InstanceGroup, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups/%v", req.GetProject(), req.GetZone(), req.GetInstanceGroup())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroup{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an instance group in the specified project using the parameters that are included in the request.
+func (c *instanceGroupsRESTClient) Insert(ctx context.Context, req *computepb.InsertInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of zonal instance group resources contained within the specified zone.
+//
+// For managed instance groups, use the instanceGroupManagers or regionInstanceGroupManagers methods instead.
+func (c *instanceGroupsRESTClient) List(ctx context.Context, req *computepb.ListInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.InstanceGroupList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListInstances lists the instances in the specified instance group. The orderBy query parameter is not supported.
+func (c *instanceGroupsRESTClient) ListInstances(ctx context.Context, req *computepb.ListInstancesInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.InstanceGroupsListInstances, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupsListInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups/%v/listInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupsListInstances{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveInstances removes one or more instances from the specified instance group, but does not delete those instances.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration before the VM instance is removed or deleted.
+func (c *instanceGroupsRESTClient) RemoveInstances(ctx context.Context, req *computepb.RemoveInstancesInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupsRemoveInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups/%v/removeInstances", req.GetProject(), req.GetZone(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetNamedPorts sets the named ports for the specified instance group.
+func (c *instanceGroupsRESTClient) SetNamedPorts(ctx context.Context, req *computepb.SetNamedPortsInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupsSetNamedPortsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instanceGroups/%v/setNamedPorts", req.GetProject(), req.GetZone(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/instance_groups_client_example_test.go b/compute/apiv1/instance_groups_client_example_test.go
new file mode 100644
index 0000000..8e646af
--- /dev/null
+++ b/compute/apiv1/instance_groups_client_example_test.go
@@ -0,0 +1,207 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInstanceGroupsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInstanceGroupsClient_AddInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddInstancesInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListInstanceGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInstanceGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_ListInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInstancesInstanceGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_RemoveInstances() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveInstancesInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceGroupsClient_SetNamedPorts() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetNamedPortsInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetNamedPorts(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/instance_templates_client.go b/compute/apiv1/instance_templates_client.go
new file mode 100644
index 0000000..2003c35
--- /dev/null
+++ b/compute/apiv1/instance_templates_client.go
@@ -0,0 +1,539 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInstanceTemplatesClientHook clientHook
+
+// InstanceTemplatesCallOptions contains the retry settings for each method of InstanceTemplatesClient.
+type InstanceTemplatesCallOptions struct {
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalInstanceTemplatesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInstanceTemplatesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteInstanceTemplateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetInstanceTemplateRequest, ...gax.CallOption) (*computepb.InstanceTemplate, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyInstanceTemplateRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertInstanceTemplateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListInstanceTemplatesRequest, ...gax.CallOption) (*computepb.InstanceTemplateList, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyInstanceTemplateRequest, ...gax.CallOption) (*computepb.Policy, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsInstanceTemplateRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// InstanceTemplatesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The InstanceTemplates API.
+type InstanceTemplatesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInstanceTemplatesClient
+
+	// The call options for this service.
+	CallOptions *InstanceTemplatesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InstanceTemplatesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InstanceTemplatesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InstanceTemplatesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified instance template. Deleting an instance template is permanent and cannot be undone. It is not possible to delete templates that are already in use by a managed instance group.
+func (c *InstanceTemplatesClient) Delete(ctx context.Context, req *computepb.DeleteInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified instance template. Gets a list of available instance templates by making a list() request.
+func (c *InstanceTemplatesClient) Get(ctx context.Context, req *computepb.GetInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.InstanceTemplate, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *InstanceTemplatesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates an instance template in the specified project using the data that is included in the request. If you are creating a new template to update an existing instance group, your new instance template must use the same network or, if applicable, the same subnetwork as the original template.
+func (c *InstanceTemplatesClient) Insert(ctx context.Context, req *computepb.InsertInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of instance templates that are contained within the specified project.
+func (c *InstanceTemplatesClient) List(ctx context.Context, req *computepb.ListInstanceTemplatesRequest, opts ...gax.CallOption) (*computepb.InstanceTemplateList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *InstanceTemplatesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *InstanceTemplatesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type instanceTemplatesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInstanceTemplatesRESTClient creates a new instance templates rest client.
+//
+// The InstanceTemplates API.
+func NewInstanceTemplatesRESTClient(ctx context.Context, opts ...option.ClientOption) (*InstanceTemplatesClient, error) {
+	clientOpts := append(defaultInstanceTemplatesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &instanceTemplatesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InstanceTemplatesClient{internalClient: c, CallOptions: &InstanceTemplatesCallOptions{}}, nil
+}
+
+func defaultInstanceTemplatesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *instanceTemplatesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *instanceTemplatesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *instanceTemplatesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified instance template. Deleting an instance template is permanent and cannot be undone. It is not possible to delete templates that are already in use by a managed instance group.
+func (c *instanceTemplatesRESTClient) Delete(ctx context.Context, req *computepb.DeleteInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates/%v", req.GetProject(), req.GetInstanceTemplate())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified instance template. Gets a list of available instance templates by making a list() request.
+func (c *instanceTemplatesRESTClient) Get(ctx context.Context, req *computepb.GetInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.InstanceTemplate, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates/%v", req.GetProject(), req.GetInstanceTemplate())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceTemplate{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *instanceTemplatesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates/%v/getIamPolicy", req.GetProject(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an instance template in the specified project using the data that is included in the request. If you are creating a new template to update an existing instance group, your new instance template must use the same network or, if applicable, the same subnetwork as the original template.
+func (c *instanceTemplatesRESTClient) Insert(ctx context.Context, req *computepb.InsertInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceTemplateResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of instance templates that are contained within the specified project.
+func (c *instanceTemplatesRESTClient) List(ctx context.Context, req *computepb.ListInstanceTemplatesRequest, opts ...gax.CallOption) (*computepb.InstanceTemplateList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceTemplateList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *instanceTemplatesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates/%v/setIamPolicy", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *instanceTemplatesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsInstanceTemplateRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/instanceTemplates/%v/testIamPermissions", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/instance_templates_client_example_test.go b/compute/apiv1/instance_templates_client_example_test.go
new file mode 100644
index 0000000..3cdbbab
--- /dev/null
+++ b/compute/apiv1/instance_templates_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInstanceTemplatesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInstanceTemplatesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInstanceTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceTemplatesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInstanceTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceTemplatesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyInstanceTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceTemplatesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertInstanceTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceTemplatesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInstanceTemplatesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceTemplatesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyInstanceTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstanceTemplatesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewInstanceTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsInstanceTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/instances_client.go b/compute/apiv1/instances_client.go
new file mode 100644
index 0000000..365b3ef
--- /dev/null
+++ b/compute/apiv1/instances_client.go
@@ -0,0 +1,2614 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInstancesClientHook clientHook
+
+// InstancesCallOptions contains the retry settings for each method of InstancesClient.
+type InstancesCallOptions struct {
+	AddAccessConfig                    []gax.CallOption
+	AddResourcePolicies                []gax.CallOption
+	AggregatedList                     []gax.CallOption
+	AttachDisk                         []gax.CallOption
+	BulkInsert                         []gax.CallOption
+	Delete                             []gax.CallOption
+	DeleteAccessConfig                 []gax.CallOption
+	DetachDisk                         []gax.CallOption
+	Get                                []gax.CallOption
+	GetEffectiveFirewalls              []gax.CallOption
+	GetGuestAttributes                 []gax.CallOption
+	GetIamPolicy                       []gax.CallOption
+	GetScreenshot                      []gax.CallOption
+	GetSerialPortOutput                []gax.CallOption
+	GetShieldedInstanceIdentity        []gax.CallOption
+	Insert                             []gax.CallOption
+	List                               []gax.CallOption
+	ListReferrers                      []gax.CallOption
+	RemoveResourcePolicies             []gax.CallOption
+	Reset                              []gax.CallOption
+	SetDeletionProtection              []gax.CallOption
+	SetDiskAutoDelete                  []gax.CallOption
+	SetIamPolicy                       []gax.CallOption
+	SetLabels                          []gax.CallOption
+	SetMachineResources                []gax.CallOption
+	SetMachineType                     []gax.CallOption
+	SetMetadata                        []gax.CallOption
+	SetMinCpuPlatform                  []gax.CallOption
+	SetScheduling                      []gax.CallOption
+	SetServiceAccount                  []gax.CallOption
+	SetShieldedInstanceIntegrityPolicy []gax.CallOption
+	SetTags                            []gax.CallOption
+	SimulateMaintenanceEvent           []gax.CallOption
+	Start                              []gax.CallOption
+	StartWithEncryptionKey             []gax.CallOption
+	Stop                               []gax.CallOption
+	TestIamPermissions                 []gax.CallOption
+	Update                             []gax.CallOption
+	UpdateAccessConfig                 []gax.CallOption
+	UpdateDisplayDevice                []gax.CallOption
+	UpdateNetworkInterface             []gax.CallOption
+	UpdateShieldedInstanceConfig       []gax.CallOption
+}
+
+// internalInstancesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInstancesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddAccessConfig(context.Context, *computepb.AddAccessConfigInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AddResourcePolicies(context.Context, *computepb.AddResourcePoliciesInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListInstancesRequest, ...gax.CallOption) (*computepb.InstanceAggregatedList, error)
+	AttachDisk(context.Context, *computepb.AttachDiskInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	BulkInsert(context.Context, *computepb.BulkInsertInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeleteAccessConfig(context.Context, *computepb.DeleteAccessConfigInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DetachDisk(context.Context, *computepb.DetachDiskInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetInstanceRequest, ...gax.CallOption) (*computepb.Instance, error)
+	GetEffectiveFirewalls(context.Context, *computepb.GetEffectiveFirewallsInstanceRequest, ...gax.CallOption) (*computepb.InstancesGetEffectiveFirewallsResponse, error)
+	GetGuestAttributes(context.Context, *computepb.GetGuestAttributesInstanceRequest, ...gax.CallOption) (*computepb.GuestAttributes, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyInstanceRequest, ...gax.CallOption) (*computepb.Policy, error)
+	GetScreenshot(context.Context, *computepb.GetScreenshotInstanceRequest, ...gax.CallOption) (*computepb.Screenshot, error)
+	GetSerialPortOutput(context.Context, *computepb.GetSerialPortOutputInstanceRequest, ...gax.CallOption) (*computepb.SerialPortOutput, error)
+	GetShieldedInstanceIdentity(context.Context, *computepb.GetShieldedInstanceIdentityInstanceRequest, ...gax.CallOption) (*computepb.ShieldedInstanceIdentity, error)
+	Insert(context.Context, *computepb.InsertInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListInstancesRequest, ...gax.CallOption) (*computepb.InstanceList, error)
+	ListReferrers(context.Context, *computepb.ListReferrersInstancesRequest, ...gax.CallOption) (*computepb.InstanceListReferrers, error)
+	RemoveResourcePolicies(context.Context, *computepb.RemoveResourcePoliciesInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Reset(context.Context, *computepb.ResetInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetDeletionProtection(context.Context, *computepb.SetDeletionProtectionInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetDiskAutoDelete(context.Context, *computepb.SetDiskAutoDeleteInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyInstanceRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetLabels(context.Context, *computepb.SetLabelsInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetMachineResources(context.Context, *computepb.SetMachineResourcesInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetMachineType(context.Context, *computepb.SetMachineTypeInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetMetadata(context.Context, *computepb.SetMetadataInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetMinCpuPlatform(context.Context, *computepb.SetMinCpuPlatformInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetScheduling(context.Context, *computepb.SetSchedulingInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetServiceAccount(context.Context, *computepb.SetServiceAccountInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetShieldedInstanceIntegrityPolicy(context.Context, *computepb.SetShieldedInstanceIntegrityPolicyInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetTags(context.Context, *computepb.SetTagsInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SimulateMaintenanceEvent(context.Context, *computepb.SimulateMaintenanceEventInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Start(context.Context, *computepb.StartInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	StartWithEncryptionKey(context.Context, *computepb.StartWithEncryptionKeyInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Stop(context.Context, *computepb.StopInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsInstanceRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+	Update(context.Context, *computepb.UpdateInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdateAccessConfig(context.Context, *computepb.UpdateAccessConfigInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdateDisplayDevice(context.Context, *computepb.UpdateDisplayDeviceInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdateNetworkInterface(context.Context, *computepb.UpdateNetworkInterfaceInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdateShieldedInstanceConfig(context.Context, *computepb.UpdateShieldedInstanceConfigInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// InstancesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Instances API.
+type InstancesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInstancesClient
+
+	// The call options for this service.
+	CallOptions *InstancesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InstancesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InstancesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InstancesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddAccessConfig adds an access config to an instance’s network interface.
+func (c *InstancesClient) AddAccessConfig(ctx context.Context, req *computepb.AddAccessConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddAccessConfig(ctx, req, opts...)
+}
+
+// AddResourcePolicies adds existing resource policies to an instance. You can only add one policy right now which will be applied to this instance for scheduling live migrations.
+func (c *InstancesClient) AddResourcePolicies(ctx context.Context, req *computepb.AddResourcePoliciesInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddResourcePolicies(ctx, req, opts...)
+}
+
+// AggregatedList retrieves aggregated list of all of the instances in your project across all regions and zones.
+func (c *InstancesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInstancesRequest, opts ...gax.CallOption) (*computepb.InstanceAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// AttachDisk attaches an existing Disk resource to an instance. You must first create the disk before you can attach it. It is not possible to create and attach a disk at the same time. For more information, read Adding a persistent disk to your instance.
+func (c *InstancesClient) AttachDisk(ctx context.Context, req *computepb.AttachDiskInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AttachDisk(ctx, req, opts...)
+}
+
+// BulkInsert creates multiple instances. Count specifies the number of instances to create.
+func (c *InstancesClient) BulkInsert(ctx context.Context, req *computepb.BulkInsertInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.BulkInsert(ctx, req, opts...)
+}
+
+// Delete deletes the specified Instance resource. For more information, see Deleting an instance.
+func (c *InstancesClient) Delete(ctx context.Context, req *computepb.DeleteInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DeleteAccessConfig deletes an access config from an instance’s network interface.
+func (c *InstancesClient) DeleteAccessConfig(ctx context.Context, req *computepb.DeleteAccessConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeleteAccessConfig(ctx, req, opts...)
+}
+
+// DetachDisk detaches a disk from an instance.
+func (c *InstancesClient) DetachDisk(ctx context.Context, req *computepb.DetachDiskInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DetachDisk(ctx, req, opts...)
+}
+
+// Get returns the specified Instance resource. Gets a list of available instances by making a list() request.
+func (c *InstancesClient) Get(ctx context.Context, req *computepb.GetInstanceRequest, opts ...gax.CallOption) (*computepb.Instance, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetEffectiveFirewalls returns effective firewalls applied to an interface of the instance.
+func (c *InstancesClient) GetEffectiveFirewalls(ctx context.Context, req *computepb.GetEffectiveFirewallsInstanceRequest, opts ...gax.CallOption) (*computepb.InstancesGetEffectiveFirewallsResponse, error) {
+	return c.internalClient.GetEffectiveFirewalls(ctx, req, opts...)
+}
+
+// GetGuestAttributes returns the specified guest attributes entry.
+func (c *InstancesClient) GetGuestAttributes(ctx context.Context, req *computepb.GetGuestAttributesInstanceRequest, opts ...gax.CallOption) (*computepb.GuestAttributes, error) {
+	return c.internalClient.GetGuestAttributes(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *InstancesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyInstanceRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// GetScreenshot returns the screenshot from the specified instance.
+func (c *InstancesClient) GetScreenshot(ctx context.Context, req *computepb.GetScreenshotInstanceRequest, opts ...gax.CallOption) (*computepb.Screenshot, error) {
+	return c.internalClient.GetScreenshot(ctx, req, opts...)
+}
+
+// GetSerialPortOutput returns the last 1 MB of serial port output from the specified instance.
+func (c *InstancesClient) GetSerialPortOutput(ctx context.Context, req *computepb.GetSerialPortOutputInstanceRequest, opts ...gax.CallOption) (*computepb.SerialPortOutput, error) {
+	return c.internalClient.GetSerialPortOutput(ctx, req, opts...)
+}
+
+// GetShieldedInstanceIdentity returns the Shielded Instance Identity of an instance
+func (c *InstancesClient) GetShieldedInstanceIdentity(ctx context.Context, req *computepb.GetShieldedInstanceIdentityInstanceRequest, opts ...gax.CallOption) (*computepb.ShieldedInstanceIdentity, error) {
+	return c.internalClient.GetShieldedInstanceIdentity(ctx, req, opts...)
+}
+
+// Insert creates an instance resource in the specified project using the data included in the request.
+func (c *InstancesClient) Insert(ctx context.Context, req *computepb.InsertInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of instances contained within the specified zone.
+func (c *InstancesClient) List(ctx context.Context, req *computepb.ListInstancesRequest, opts ...gax.CallOption) (*computepb.InstanceList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListReferrers retrieves a list of resources that refer to the VM instance specified in the request. For example, if the VM instance is part of a managed or unmanaged instance group, the referrers list includes the instance group. For more information, read Viewing referrers to VM instances.
+func (c *InstancesClient) ListReferrers(ctx context.Context, req *computepb.ListReferrersInstancesRequest, opts ...gax.CallOption) (*computepb.InstanceListReferrers, error) {
+	return c.internalClient.ListReferrers(ctx, req, opts...)
+}
+
+// RemoveResourcePolicies removes resource policies from an instance.
+func (c *InstancesClient) RemoveResourcePolicies(ctx context.Context, req *computepb.RemoveResourcePoliciesInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveResourcePolicies(ctx, req, opts...)
+}
+
+// Reset performs a reset on the instance. This is a hard reset the VM does not do a graceful shutdown. For more information, see Resetting an instance.
+func (c *InstancesClient) Reset(ctx context.Context, req *computepb.ResetInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Reset(ctx, req, opts...)
+}
+
+// SetDeletionProtection sets deletion protection on the instance.
+func (c *InstancesClient) SetDeletionProtection(ctx context.Context, req *computepb.SetDeletionProtectionInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetDeletionProtection(ctx, req, opts...)
+}
+
+// SetDiskAutoDelete sets the auto-delete flag for a disk attached to an instance.
+func (c *InstancesClient) SetDiskAutoDelete(ctx context.Context, req *computepb.SetDiskAutoDeleteInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetDiskAutoDelete(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *InstancesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyInstanceRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetLabels sets labels on an instance. To learn more about labels, read the Labeling Resources documentation.
+func (c *InstancesClient) SetLabels(ctx context.Context, req *computepb.SetLabelsInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// SetMachineResources changes the number and/or type of accelerator for a stopped instance to the values specified in the request.
+func (c *InstancesClient) SetMachineResources(ctx context.Context, req *computepb.SetMachineResourcesInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetMachineResources(ctx, req, opts...)
+}
+
+// SetMachineType changes the machine type for a stopped instance to the machine type specified in the request.
+func (c *InstancesClient) SetMachineType(ctx context.Context, req *computepb.SetMachineTypeInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetMachineType(ctx, req, opts...)
+}
+
+// SetMetadata sets metadata for the specified instance to the data included in the request.
+func (c *InstancesClient) SetMetadata(ctx context.Context, req *computepb.SetMetadataInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetMetadata(ctx, req, opts...)
+}
+
+// SetMinCpuPlatform changes the minimum CPU platform that this instance should use. This method can only be called on a stopped instance. For more information, read Specifying a Minimum CPU Platform.
+func (c *InstancesClient) SetMinCpuPlatform(ctx context.Context, req *computepb.SetMinCpuPlatformInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetMinCpuPlatform(ctx, req, opts...)
+}
+
+// SetScheduling sets an instance’s scheduling options. You can only call this method on a stopped instance, that is, a VM instance that is in a TERMINATED state. See Instance Life Cycle for more information on the possible instance states.
+func (c *InstancesClient) SetScheduling(ctx context.Context, req *computepb.SetSchedulingInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetScheduling(ctx, req, opts...)
+}
+
+// SetServiceAccount sets the service account on the instance. For more information, read Changing the service account and access scopes for an instance.
+func (c *InstancesClient) SetServiceAccount(ctx context.Context, req *computepb.SetServiceAccountInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetServiceAccount(ctx, req, opts...)
+}
+
+// SetShieldedInstanceIntegrityPolicy sets the Shielded Instance integrity policy for an instance. You can only use this method on a running instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InstancesClient) SetShieldedInstanceIntegrityPolicy(ctx context.Context, req *computepb.SetShieldedInstanceIntegrityPolicyInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetShieldedInstanceIntegrityPolicy(ctx, req, opts...)
+}
+
+// SetTags sets network tags for the specified instance to the data included in the request.
+func (c *InstancesClient) SetTags(ctx context.Context, req *computepb.SetTagsInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetTags(ctx, req, opts...)
+}
+
+// SimulateMaintenanceEvent simulates a maintenance event on the instance.
+func (c *InstancesClient) SimulateMaintenanceEvent(ctx context.Context, req *computepb.SimulateMaintenanceEventInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SimulateMaintenanceEvent(ctx, req, opts...)
+}
+
+// Start starts an instance that was stopped using the instances().stop method. For more information, see Restart an instance.
+func (c *InstancesClient) Start(ctx context.Context, req *computepb.StartInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Start(ctx, req, opts...)
+}
+
+// StartWithEncryptionKey starts an instance that was stopped using the instances().stop method. For more information, see Restart an instance.
+func (c *InstancesClient) StartWithEncryptionKey(ctx context.Context, req *computepb.StartWithEncryptionKeyInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.StartWithEncryptionKey(ctx, req, opts...)
+}
+
+// Stop stops a running instance, shutting it down cleanly, and allows you to restart the instance at a later time. Stopped instances do not incur VM usage charges while they are stopped. However, resources that the VM is using, such as persistent disks and static IP addresses, will continue to be charged until they are deleted. For more information, see Stopping an instance.
+func (c *InstancesClient) Stop(ctx context.Context, req *computepb.StopInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Stop(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *InstancesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsInstanceRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Update updates an instance only if the necessary resources are available. This method can update only a specific set of instance properties. See  Updating a running instance for a list of updatable instance properties.
+func (c *InstancesClient) Update(ctx context.Context, req *computepb.UpdateInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// UpdateAccessConfig updates the specified access config from an instance’s network interface with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InstancesClient) UpdateAccessConfig(ctx context.Context, req *computepb.UpdateAccessConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdateAccessConfig(ctx, req, opts...)
+}
+
+// UpdateDisplayDevice updates the Display config for a VM instance. You can only use this method on a stopped VM instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InstancesClient) UpdateDisplayDevice(ctx context.Context, req *computepb.UpdateDisplayDeviceInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdateDisplayDevice(ctx, req, opts...)
+}
+
+// UpdateNetworkInterface updates an instance’s network interface. This method can only update an interface’s alias IP range and attached network. See Modifying alias IP ranges for an existing instance for instructions on changing alias IP ranges. See Migrating a VM between networks for instructions on migrating an interface. This method follows PATCH semantics.
+func (c *InstancesClient) UpdateNetworkInterface(ctx context.Context, req *computepb.UpdateNetworkInterfaceInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdateNetworkInterface(ctx, req, opts...)
+}
+
+// UpdateShieldedInstanceConfig updates the Shielded Instance config for an instance. You can only use this method on a stopped instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InstancesClient) UpdateShieldedInstanceConfig(ctx context.Context, req *computepb.UpdateShieldedInstanceConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdateShieldedInstanceConfig(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type instancesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInstancesRESTClient creates a new instances rest client.
+//
+// The Instances API.
+func NewInstancesRESTClient(ctx context.Context, opts ...option.ClientOption) (*InstancesClient, error) {
+	clientOpts := append(defaultInstancesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &instancesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InstancesClient{internalClient: c, CallOptions: &InstancesCallOptions{}}, nil
+}
+
+func defaultInstancesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *instancesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *instancesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *instancesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddAccessConfig adds an access config to an instance’s network interface.
+func (c *instancesRESTClient) AddAccessConfig(ctx context.Context, req *computepb.AddAccessConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAccessConfigResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/addAccessConfig", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetNetworkInterface() != "" {
+		params.Add("networkInterface", fmt.Sprintf("%v", req.GetNetworkInterface()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AddResourcePolicies adds existing resource policies to an instance. You can only add one policy right now which will be applied to this instance for scheduling live migrations.
+func (c *instancesRESTClient) AddResourcePolicies(ctx context.Context, req *computepb.AddResourcePoliciesInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesAddResourcePoliciesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/addResourcePolicies", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves aggregated list of all of the instances in your project across all regions and zones.
+func (c *instancesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInstancesRequest, opts ...gax.CallOption) (*computepb.InstanceAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/instances", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AttachDisk attaches an existing Disk resource to an instance. You must first create the disk before you can attach it. It is not possible to create and attach a disk at the same time. For more information, read Adding a persistent disk to your instance.
+func (c *instancesRESTClient) AttachDisk(ctx context.Context, req *computepb.AttachDiskInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAttachedDiskResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/attachDisk", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.ForceAttach != nil {
+		params.Add("forceAttach", fmt.Sprintf("%v", req.GetForceAttach()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// BulkInsert creates multiple instances. Count specifies the number of instances to create.
+func (c *instancesRESTClient) BulkInsert(ctx context.Context, req *computepb.BulkInsertInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBulkInsertInstanceResourceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/bulkInsert", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified Instance resource. For more information, see Deleting an instance.
+func (c *instancesRESTClient) Delete(ctx context.Context, req *computepb.DeleteInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeleteAccessConfig deletes an access config from an instance’s network interface.
+func (c *instancesRESTClient) DeleteAccessConfig(ctx context.Context, req *computepb.DeleteAccessConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/deleteAccessConfig", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetAccessConfig() != "" {
+		params.Add("accessConfig", fmt.Sprintf("%v", req.GetAccessConfig()))
+	}
+	if req.GetNetworkInterface() != "" {
+		params.Add("networkInterface", fmt.Sprintf("%v", req.GetNetworkInterface()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DetachDisk detaches a disk from an instance.
+func (c *instancesRESTClient) DetachDisk(ctx context.Context, req *computepb.DetachDiskInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/detachDisk", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetDeviceName() != "" {
+		params.Add("deviceName", fmt.Sprintf("%v", req.GetDeviceName()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified Instance resource. Gets a list of available instances by making a list() request.
+func (c *instancesRESTClient) Get(ctx context.Context, req *computepb.GetInstanceRequest, opts ...gax.CallOption) (*computepb.Instance, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Instance{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetEffectiveFirewalls returns effective firewalls applied to an interface of the instance.
+func (c *instancesRESTClient) GetEffectiveFirewalls(ctx context.Context, req *computepb.GetEffectiveFirewallsInstanceRequest, opts ...gax.CallOption) (*computepb.InstancesGetEffectiveFirewallsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/getEffectiveFirewalls", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetNetworkInterface() != "" {
+		params.Add("networkInterface", fmt.Sprintf("%v", req.GetNetworkInterface()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstancesGetEffectiveFirewallsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetGuestAttributes returns the specified guest attributes entry.
+func (c *instancesRESTClient) GetGuestAttributes(ctx context.Context, req *computepb.GetGuestAttributesInstanceRequest, opts ...gax.CallOption) (*computepb.GuestAttributes, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/getGuestAttributes", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.QueryPath != nil {
+		params.Add("queryPath", fmt.Sprintf("%v", req.GetQueryPath()))
+	}
+	if req != nil && req.VariableKey != nil {
+		params.Add("variableKey", fmt.Sprintf("%v", req.GetVariableKey()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.GuestAttributes{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *instancesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyInstanceRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/getIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetScreenshot returns the screenshot from the specified instance.
+func (c *instancesRESTClient) GetScreenshot(ctx context.Context, req *computepb.GetScreenshotInstanceRequest, opts ...gax.CallOption) (*computepb.Screenshot, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/screenshot", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Screenshot{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetSerialPortOutput returns the last 1 MB of serial port output from the specified instance.
+func (c *instancesRESTClient) GetSerialPortOutput(ctx context.Context, req *computepb.GetSerialPortOutputInstanceRequest, opts ...gax.CallOption) (*computepb.SerialPortOutput, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/serialPort", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.Port != nil {
+		params.Add("port", fmt.Sprintf("%v", req.GetPort()))
+	}
+	if req != nil && req.Start != nil {
+		params.Add("start", fmt.Sprintf("%v", req.GetStart()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SerialPortOutput{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetShieldedInstanceIdentity returns the Shielded Instance Identity of an instance
+func (c *instancesRESTClient) GetShieldedInstanceIdentity(ctx context.Context, req *computepb.GetShieldedInstanceIdentityInstanceRequest, opts ...gax.CallOption) (*computepb.ShieldedInstanceIdentity, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/getShieldedInstanceIdentity", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ShieldedInstanceIdentity{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an instance resource in the specified project using the data included in the request.
+func (c *instancesRESTClient) Insert(ctx context.Context, req *computepb.InsertInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req != nil && req.SourceInstanceTemplate != nil {
+		params.Add("sourceInstanceTemplate", fmt.Sprintf("%v", req.GetSourceInstanceTemplate()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of instances contained within the specified zone.
+func (c *instancesRESTClient) List(ctx context.Context, req *computepb.ListInstancesRequest, opts ...gax.CallOption) (*computepb.InstanceList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListReferrers retrieves a list of resources that refer to the VM instance specified in the request. For example, if the VM instance is part of a managed or unmanaged instance group, the referrers list includes the instance group. For more information, read Viewing referrers to VM instances.
+func (c *instancesRESTClient) ListReferrers(ctx context.Context, req *computepb.ListReferrersInstancesRequest, opts ...gax.CallOption) (*computepb.InstanceListReferrers, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/referrers", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceListReferrers{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveResourcePolicies removes resource policies from an instance.
+func (c *instancesRESTClient) RemoveResourcePolicies(ctx context.Context, req *computepb.RemoveResourcePoliciesInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesRemoveResourcePoliciesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/removeResourcePolicies", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Reset performs a reset on the instance. This is a hard reset the VM does not do a graceful shutdown. For more information, see Resetting an instance.
+func (c *instancesRESTClient) Reset(ctx context.Context, req *computepb.ResetInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/reset", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetDeletionProtection sets deletion protection on the instance.
+func (c *instancesRESTClient) SetDeletionProtection(ctx context.Context, req *computepb.SetDeletionProtectionInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setDeletionProtection", req.GetProject(), req.GetZone(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.DeletionProtection != nil {
+		params.Add("deletionProtection", fmt.Sprintf("%v", req.GetDeletionProtection()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetDiskAutoDelete sets the auto-delete flag for a disk attached to an instance.
+func (c *instancesRESTClient) SetDiskAutoDelete(ctx context.Context, req *computepb.SetDiskAutoDeleteInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setDiskAutoDelete", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetAutoDelete() {
+		params.Add("autoDelete", fmt.Sprintf("%v", req.GetAutoDelete()))
+	}
+	if req.GetDeviceName() != "" {
+		params.Add("deviceName", fmt.Sprintf("%v", req.GetDeviceName()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *instancesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyInstanceRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetZoneSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets labels on an instance. To learn more about labels, read the Labeling Resources documentation.
+func (c *instancesRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setLabels", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetMachineResources changes the number and/or type of accelerator for a stopped instance to the values specified in the request.
+func (c *instancesRESTClient) SetMachineResources(ctx context.Context, req *computepb.SetMachineResourcesInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesSetMachineResourcesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setMachineResources", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetMachineType changes the machine type for a stopped instance to the machine type specified in the request.
+func (c *instancesRESTClient) SetMachineType(ctx context.Context, req *computepb.SetMachineTypeInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesSetMachineTypeRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setMachineType", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetMetadata sets metadata for the specified instance to the data included in the request.
+func (c *instancesRESTClient) SetMetadata(ctx context.Context, req *computepb.SetMetadataInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetMetadataResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setMetadata", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetMinCpuPlatform changes the minimum CPU platform that this instance should use. This method can only be called on a stopped instance. For more information, read Specifying a Minimum CPU Platform.
+func (c *instancesRESTClient) SetMinCpuPlatform(ctx context.Context, req *computepb.SetMinCpuPlatformInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesSetMinCpuPlatformRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setMinCpuPlatform", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetScheduling sets an instance’s scheduling options. You can only call this method on a stopped instance, that is, a VM instance that is in a TERMINATED state. See Instance Life Cycle for more information on the possible instance states.
+func (c *instancesRESTClient) SetScheduling(ctx context.Context, req *computepb.SetSchedulingInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSchedulingResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setScheduling", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetServiceAccount sets the service account on the instance. For more information, read Changing the service account and access scopes for an instance.
+func (c *instancesRESTClient) SetServiceAccount(ctx context.Context, req *computepb.SetServiceAccountInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesSetServiceAccountRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setServiceAccount", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetShieldedInstanceIntegrityPolicy sets the Shielded Instance integrity policy for an instance. You can only use this method on a running instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *instancesRESTClient) SetShieldedInstanceIntegrityPolicy(ctx context.Context, req *computepb.SetShieldedInstanceIntegrityPolicyInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetShieldedInstanceIntegrityPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setShieldedInstanceIntegrityPolicy", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetTags sets network tags for the specified instance to the data included in the request.
+func (c *instancesRESTClient) SetTags(ctx context.Context, req *computepb.SetTagsInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTagsResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/setTags", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SimulateMaintenanceEvent simulates a maintenance event on the instance.
+func (c *instancesRESTClient) SimulateMaintenanceEvent(ctx context.Context, req *computepb.SimulateMaintenanceEventInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/simulateMaintenanceEvent", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Start starts an instance that was stopped using the instances().stop method. For more information, see Restart an instance.
+func (c *instancesRESTClient) Start(ctx context.Context, req *computepb.StartInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/start", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// StartWithEncryptionKey starts an instance that was stopped using the instances().stop method. For more information, see Restart an instance.
+func (c *instancesRESTClient) StartWithEncryptionKey(ctx context.Context, req *computepb.StartWithEncryptionKeyInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstancesStartWithEncryptionKeyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/startWithEncryptionKey", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Stop stops a running instance, shutting it down cleanly, and allows you to restart the instance at a later time. Stopped instances do not incur VM usage charges while they are stopped. However, resources that the VM is using, such as persistent disks and static IP addresses, will continue to be charged until they are deleted. For more information, see Stopping an instance.
+func (c *instancesRESTClient) Stop(ctx context.Context, req *computepb.StopInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/stop", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *instancesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsInstanceRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/testIamPermissions", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates an instance only if the necessary resources are available. This method can update only a specific set of instance properties. See  Updating a running instance for a list of updatable instance properties.
+func (c *instancesRESTClient) Update(ctx context.Context, req *computepb.UpdateInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetInstance() != "" {
+		params.Add("instance", fmt.Sprintf("%v", req.GetInstance()))
+	}
+	if req != nil && req.MinimalAction != nil {
+		params.Add("minimalAction", fmt.Sprintf("%v", req.GetMinimalAction()))
+	}
+	if req != nil && req.MostDisruptiveAllowedAction != nil {
+		params.Add("mostDisruptiveAllowedAction", fmt.Sprintf("%v", req.GetMostDisruptiveAllowedAction()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetZone() != "" {
+		params.Add("zone", fmt.Sprintf("%v", req.GetZone()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdateAccessConfig updates the specified access config from an instance’s network interface with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *instancesRESTClient) UpdateAccessConfig(ctx context.Context, req *computepb.UpdateAccessConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAccessConfigResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/updateAccessConfig", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetNetworkInterface() != "" {
+		params.Add("networkInterface", fmt.Sprintf("%v", req.GetNetworkInterface()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdateDisplayDevice updates the Display config for a VM instance. You can only use this method on a stopped VM instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *instancesRESTClient) UpdateDisplayDevice(ctx context.Context, req *computepb.UpdateDisplayDeviceInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDisplayDeviceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/updateDisplayDevice", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdateNetworkInterface updates an instance’s network interface. This method can only update an interface’s alias IP range and attached network. See Modifying alias IP ranges for an existing instance for instructions on changing alias IP ranges. See Migrating a VM between networks for instructions on migrating an interface. This method follows PATCH semantics.
+func (c *instancesRESTClient) UpdateNetworkInterface(ctx context.Context, req *computepb.UpdateNetworkInterfaceInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkInterfaceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/updateNetworkInterface", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req.GetNetworkInterface() != "" {
+		params.Add("networkInterface", fmt.Sprintf("%v", req.GetNetworkInterface()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdateShieldedInstanceConfig updates the Shielded Instance config for an instance. You can only use this method on a stopped instance. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *instancesRESTClient) UpdateShieldedInstanceConfig(ctx context.Context, req *computepb.UpdateShieldedInstanceConfigInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetShieldedInstanceConfigResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/instances/%v/updateShieldedInstanceConfig", req.GetProject(), req.GetZone(), req.GetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/instances_client_example_test.go b/compute/apiv1/instances_client_example_test.go
new file mode 100644
index 0000000..3728bb8
--- /dev/null
+++ b/compute/apiv1/instances_client_example_test.go
@@ -0,0 +1,834 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInstancesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInstancesClient_AddAccessConfig() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddAccessConfigInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddAccessConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_AddResourcePolicies() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddResourcePoliciesInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddResourcePolicies(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListInstancesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_AttachDisk() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AttachDiskInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AttachDisk(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_BulkInsert() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.BulkInsertInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.BulkInsert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_DeleteAccessConfig() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteAccessConfigInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeleteAccessConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_DetachDisk() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DetachDiskInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DetachDisk(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_GetEffectiveFirewalls() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetEffectiveFirewallsInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetEffectiveFirewalls(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_GetGuestAttributes() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetGuestAttributesInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetGuestAttributes(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_GetScreenshot() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetScreenshotInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetScreenshot(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_GetSerialPortOutput() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetSerialPortOutputInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetSerialPortOutput(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_GetShieldedInstanceIdentity() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetShieldedInstanceIdentityInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetShieldedInstanceIdentity(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInstancesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_ListReferrers() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListReferrersInstancesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListReferrers(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_RemoveResourcePolicies() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveResourcePoliciesInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveResourcePolicies(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Reset() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ResetInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Reset(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetDeletionProtection() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetDeletionProtectionInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetDeletionProtection(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetDiskAutoDelete() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetDiskAutoDeleteInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetDiskAutoDelete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetMachineResources() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetMachineResourcesInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetMachineResources(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetMachineType() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetMachineTypeInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetMachineType(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetMetadata() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetMetadataInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetMetadata(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetMinCpuPlatform() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetMinCpuPlatformInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetMinCpuPlatform(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetScheduling() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSchedulingInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetScheduling(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetServiceAccount() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetServiceAccountInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetServiceAccount(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetShieldedInstanceIntegrityPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetShieldedInstanceIntegrityPolicyInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetShieldedInstanceIntegrityPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SetTags() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetTagsInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetTags(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_SimulateMaintenanceEvent() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SimulateMaintenanceEventInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SimulateMaintenanceEvent(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Start() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.StartInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Start(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_StartWithEncryptionKey() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.StartWithEncryptionKeyInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.StartWithEncryptionKey(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Stop() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.StopInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Stop(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_UpdateAccessConfig() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateAccessConfigInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdateAccessConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_UpdateDisplayDevice() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateDisplayDeviceInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdateDisplayDevice(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_UpdateNetworkInterface() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateNetworkInterfaceInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdateNetworkInterface(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInstancesClient_UpdateShieldedInstanceConfig() {
+	ctx := context.Background()
+	c, err := compute.NewInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateShieldedInstanceConfigInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdateShieldedInstanceConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/interconnect_attachments_client.go b/compute/apiv1/interconnect_attachments_client.go
new file mode 100644
index 0000000..017f933
--- /dev/null
+++ b/compute/apiv1/interconnect_attachments_client.go
@@ -0,0 +1,513 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInterconnectAttachmentsClientHook clientHook
+
+// InterconnectAttachmentsCallOptions contains the retry settings for each method of InterconnectAttachmentsClient.
+type InterconnectAttachmentsCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+}
+
+// internalInterconnectAttachmentsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInterconnectAttachmentsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListInterconnectAttachmentsRequest, ...gax.CallOption) (*computepb.InterconnectAttachmentAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteInterconnectAttachmentRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetInterconnectAttachmentRequest, ...gax.CallOption) (*computepb.InterconnectAttachment, error)
+	Insert(context.Context, *computepb.InsertInterconnectAttachmentRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListInterconnectAttachmentsRequest, ...gax.CallOption) (*computepb.InterconnectAttachmentList, error)
+	Patch(context.Context, *computepb.PatchInterconnectAttachmentRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// InterconnectAttachmentsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The InterconnectAttachments API.
+type InterconnectAttachmentsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInterconnectAttachmentsClient
+
+	// The call options for this service.
+	CallOptions *InterconnectAttachmentsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InterconnectAttachmentsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InterconnectAttachmentsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InterconnectAttachmentsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of interconnect attachments.
+func (c *InterconnectAttachmentsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInterconnectAttachmentsRequest, opts ...gax.CallOption) (*computepb.InterconnectAttachmentAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified interconnect attachment.
+func (c *InterconnectAttachmentsClient) Delete(ctx context.Context, req *computepb.DeleteInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified interconnect attachment.
+func (c *InterconnectAttachmentsClient) Get(ctx context.Context, req *computepb.GetInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.InterconnectAttachment, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates an InterconnectAttachment in the specified project using the data included in the request.
+func (c *InterconnectAttachmentsClient) Insert(ctx context.Context, req *computepb.InsertInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of interconnect attachments contained within the specified region.
+func (c *InterconnectAttachmentsClient) List(ctx context.Context, req *computepb.ListInterconnectAttachmentsRequest, opts ...gax.CallOption) (*computepb.InterconnectAttachmentList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified interconnect attachment with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InterconnectAttachmentsClient) Patch(ctx context.Context, req *computepb.PatchInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type interconnectAttachmentsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInterconnectAttachmentsRESTClient creates a new interconnect attachments rest client.
+//
+// The InterconnectAttachments API.
+func NewInterconnectAttachmentsRESTClient(ctx context.Context, opts ...option.ClientOption) (*InterconnectAttachmentsClient, error) {
+	clientOpts := append(defaultInterconnectAttachmentsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &interconnectAttachmentsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InterconnectAttachmentsClient{internalClient: c, CallOptions: &InterconnectAttachmentsCallOptions{}}, nil
+}
+
+func defaultInterconnectAttachmentsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *interconnectAttachmentsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *interconnectAttachmentsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *interconnectAttachmentsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of interconnect attachments.
+func (c *interconnectAttachmentsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListInterconnectAttachmentsRequest, opts ...gax.CallOption) (*computepb.InterconnectAttachmentAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/interconnectAttachments", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectAttachmentAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified interconnect attachment.
+func (c *interconnectAttachmentsRESTClient) Delete(ctx context.Context, req *computepb.DeleteInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/interconnectAttachments/%v", req.GetProject(), req.GetRegion(), req.GetInterconnectAttachment())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified interconnect attachment.
+func (c *interconnectAttachmentsRESTClient) Get(ctx context.Context, req *computepb.GetInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.InterconnectAttachment, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/interconnectAttachments/%v", req.GetProject(), req.GetRegion(), req.GetInterconnectAttachment())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectAttachment{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an InterconnectAttachment in the specified project using the data included in the request.
+func (c *interconnectAttachmentsRESTClient) Insert(ctx context.Context, req *computepb.InsertInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInterconnectAttachmentResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/interconnectAttachments", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req != nil && req.ValidateOnly != nil {
+		params.Add("validateOnly", fmt.Sprintf("%v", req.GetValidateOnly()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of interconnect attachments contained within the specified region.
+func (c *interconnectAttachmentsRESTClient) List(ctx context.Context, req *computepb.ListInterconnectAttachmentsRequest, opts ...gax.CallOption) (*computepb.InterconnectAttachmentList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/interconnectAttachments", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectAttachmentList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified interconnect attachment with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *interconnectAttachmentsRESTClient) Patch(ctx context.Context, req *computepb.PatchInterconnectAttachmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInterconnectAttachmentResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/interconnectAttachments/%v", req.GetProject(), req.GetRegion(), req.GetInterconnectAttachment())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/interconnect_attachments_client_example_test.go b/compute/apiv1/interconnect_attachments_client_example_test.go
new file mode 100644
index 0000000..0f480c1
--- /dev/null
+++ b/compute/apiv1/interconnect_attachments_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInterconnectAttachmentsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInterconnectAttachmentsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListInterconnectAttachmentsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectAttachmentsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInterconnectAttachmentRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectAttachmentsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInterconnectAttachmentRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectAttachmentsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertInterconnectAttachmentRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectAttachmentsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInterconnectAttachmentsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectAttachmentsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectAttachmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchInterconnectAttachmentRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/interconnect_locations_client.go b/compute/apiv1/interconnect_locations_client.go
new file mode 100644
index 0000000..cf535f1
--- /dev/null
+++ b/compute/apiv1/interconnect_locations_client.go
@@ -0,0 +1,265 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInterconnectLocationsClientHook clientHook
+
+// InterconnectLocationsCallOptions contains the retry settings for each method of InterconnectLocationsClient.
+type InterconnectLocationsCallOptions struct {
+	Get  []gax.CallOption
+	List []gax.CallOption
+}
+
+// internalInterconnectLocationsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInterconnectLocationsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Get(context.Context, *computepb.GetInterconnectLocationRequest, ...gax.CallOption) (*computepb.InterconnectLocation, error)
+	List(context.Context, *computepb.ListInterconnectLocationsRequest, ...gax.CallOption) (*computepb.InterconnectLocationList, error)
+}
+
+// InterconnectLocationsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The InterconnectLocations API.
+type InterconnectLocationsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInterconnectLocationsClient
+
+	// The call options for this service.
+	CallOptions *InterconnectLocationsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InterconnectLocationsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InterconnectLocationsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InterconnectLocationsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Get returns the details for the specified interconnect location. Gets a list of available interconnect locations by making a list() request.
+func (c *InterconnectLocationsClient) Get(ctx context.Context, req *computepb.GetInterconnectLocationRequest, opts ...gax.CallOption) (*computepb.InterconnectLocation, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves the list of interconnect locations available to the specified project.
+func (c *InterconnectLocationsClient) List(ctx context.Context, req *computepb.ListInterconnectLocationsRequest, opts ...gax.CallOption) (*computepb.InterconnectLocationList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type interconnectLocationsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInterconnectLocationsRESTClient creates a new interconnect locations rest client.
+//
+// The InterconnectLocations API.
+func NewInterconnectLocationsRESTClient(ctx context.Context, opts ...option.ClientOption) (*InterconnectLocationsClient, error) {
+	clientOpts := append(defaultInterconnectLocationsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &interconnectLocationsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InterconnectLocationsClient{internalClient: c, CallOptions: &InterconnectLocationsCallOptions{}}, nil
+}
+
+func defaultInterconnectLocationsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *interconnectLocationsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *interconnectLocationsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *interconnectLocationsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Get returns the details for the specified interconnect location. Gets a list of available interconnect locations by making a list() request.
+func (c *interconnectLocationsRESTClient) Get(ctx context.Context, req *computepb.GetInterconnectLocationRequest, opts ...gax.CallOption) (*computepb.InterconnectLocation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnectLocations/%v", req.GetProject(), req.GetInterconnectLocation())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectLocation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of interconnect locations available to the specified project.
+func (c *interconnectLocationsRESTClient) List(ctx context.Context, req *computepb.ListInterconnectLocationsRequest, opts ...gax.CallOption) (*computepb.InterconnectLocationList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnectLocations", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectLocationList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/interconnect_locations_client_example_test.go b/compute/apiv1/interconnect_locations_client_example_test.go
new file mode 100644
index 0000000..2c48d43
--- /dev/null
+++ b/compute/apiv1/interconnect_locations_client_example_test.go
@@ -0,0 +1,74 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInterconnectLocationsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectLocationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInterconnectLocationsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectLocationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInterconnectLocationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectLocationsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectLocationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInterconnectLocationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/interconnects_client.go b/compute/apiv1/interconnects_client.go
new file mode 100644
index 0000000..26fa2f1
--- /dev/null
+++ b/compute/apiv1/interconnects_client.go
@@ -0,0 +1,488 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newInterconnectsClientHook clientHook
+
+// InterconnectsCallOptions contains the retry settings for each method of InterconnectsClient.
+type InterconnectsCallOptions struct {
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	GetDiagnostics []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+}
+
+// internalInterconnectsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalInterconnectsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteInterconnectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetInterconnectRequest, ...gax.CallOption) (*computepb.Interconnect, error)
+	GetDiagnostics(context.Context, *computepb.GetDiagnosticsInterconnectRequest, ...gax.CallOption) (*computepb.InterconnectsGetDiagnosticsResponse, error)
+	Insert(context.Context, *computepb.InsertInterconnectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListInterconnectsRequest, ...gax.CallOption) (*computepb.InterconnectList, error)
+	Patch(context.Context, *computepb.PatchInterconnectRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// InterconnectsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Interconnects API.
+type InterconnectsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalInterconnectsClient
+
+	// The call options for this service.
+	CallOptions *InterconnectsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *InterconnectsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *InterconnectsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *InterconnectsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified interconnect.
+func (c *InterconnectsClient) Delete(ctx context.Context, req *computepb.DeleteInterconnectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified interconnect. Get a list of available interconnects by making a list() request.
+func (c *InterconnectsClient) Get(ctx context.Context, req *computepb.GetInterconnectRequest, opts ...gax.CallOption) (*computepb.Interconnect, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetDiagnostics returns the interconnectDiagnostics for the specified interconnect.
+func (c *InterconnectsClient) GetDiagnostics(ctx context.Context, req *computepb.GetDiagnosticsInterconnectRequest, opts ...gax.CallOption) (*computepb.InterconnectsGetDiagnosticsResponse, error) {
+	return c.internalClient.GetDiagnostics(ctx, req, opts...)
+}
+
+// Insert creates a Interconnect in the specified project using the data included in the request.
+func (c *InterconnectsClient) Insert(ctx context.Context, req *computepb.InsertInterconnectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of interconnect available to the specified project.
+func (c *InterconnectsClient) List(ctx context.Context, req *computepb.ListInterconnectsRequest, opts ...gax.CallOption) (*computepb.InterconnectList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified interconnect with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *InterconnectsClient) Patch(ctx context.Context, req *computepb.PatchInterconnectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type interconnectsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewInterconnectsRESTClient creates a new interconnects rest client.
+//
+// The Interconnects API.
+func NewInterconnectsRESTClient(ctx context.Context, opts ...option.ClientOption) (*InterconnectsClient, error) {
+	clientOpts := append(defaultInterconnectsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &interconnectsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &InterconnectsClient{internalClient: c, CallOptions: &InterconnectsCallOptions{}}, nil
+}
+
+func defaultInterconnectsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *interconnectsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *interconnectsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *interconnectsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified interconnect.
+func (c *interconnectsRESTClient) Delete(ctx context.Context, req *computepb.DeleteInterconnectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnects/%v", req.GetProject(), req.GetInterconnect())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified interconnect. Get a list of available interconnects by making a list() request.
+func (c *interconnectsRESTClient) Get(ctx context.Context, req *computepb.GetInterconnectRequest, opts ...gax.CallOption) (*computepb.Interconnect, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnects/%v", req.GetProject(), req.GetInterconnect())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Interconnect{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetDiagnostics returns the interconnectDiagnostics for the specified interconnect.
+func (c *interconnectsRESTClient) GetDiagnostics(ctx context.Context, req *computepb.GetDiagnosticsInterconnectRequest, opts ...gax.CallOption) (*computepb.InterconnectsGetDiagnosticsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnects/%v/getDiagnostics", req.GetProject(), req.GetInterconnect())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectsGetDiagnosticsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a Interconnect in the specified project using the data included in the request.
+func (c *interconnectsRESTClient) Insert(ctx context.Context, req *computepb.InsertInterconnectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInterconnectResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnects", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of interconnect available to the specified project.
+func (c *interconnectsRESTClient) List(ctx context.Context, req *computepb.ListInterconnectsRequest, opts ...gax.CallOption) (*computepb.InterconnectList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnects", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InterconnectList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified interconnect with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *interconnectsRESTClient) Patch(ctx context.Context, req *computepb.PatchInterconnectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInterconnectResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/interconnects/%v", req.GetProject(), req.GetInterconnect())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/interconnects_client_example_test.go b/compute/apiv1/interconnects_client_example_test.go
new file mode 100644
index 0000000..dca1482
--- /dev/null
+++ b/compute/apiv1/interconnects_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewInterconnectsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleInterconnectsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInterconnectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetInterconnectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectsClient_GetDiagnostics() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetDiagnosticsInterconnectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetDiagnostics(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertInterconnectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInterconnectsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleInterconnectsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewInterconnectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchInterconnectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/license_codes_client.go b/compute/apiv1/license_codes_client.go
new file mode 100644
index 0000000..b87bb61
--- /dev/null
+++ b/compute/apiv1/license_codes_client.go
@@ -0,0 +1,247 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newLicenseCodesClientHook clientHook
+
+// LicenseCodesCallOptions contains the retry settings for each method of LicenseCodesClient.
+type LicenseCodesCallOptions struct {
+	Get                []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalLicenseCodesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalLicenseCodesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Get(context.Context, *computepb.GetLicenseCodeRequest, ...gax.CallOption) (*computepb.LicenseCode, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsLicenseCodeRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// LicenseCodesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The LicenseCodes API.
+type LicenseCodesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalLicenseCodesClient
+
+	// The call options for this service.
+	CallOptions *LicenseCodesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *LicenseCodesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *LicenseCodesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *LicenseCodesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Get return a specified license code. License codes are mirrored across all projects that have permissions to read the License Code.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicenseCodesClient) Get(ctx context.Context, req *computepb.GetLicenseCodeRequest, opts ...gax.CallOption) (*computepb.LicenseCode, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicenseCodesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsLicenseCodeRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type licenseCodesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewLicenseCodesRESTClient creates a new license codes rest client.
+//
+// The LicenseCodes API.
+func NewLicenseCodesRESTClient(ctx context.Context, opts ...option.ClientOption) (*LicenseCodesClient, error) {
+	clientOpts := append(defaultLicenseCodesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &licenseCodesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &LicenseCodesClient{internalClient: c, CallOptions: &LicenseCodesCallOptions{}}, nil
+}
+
+func defaultLicenseCodesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *licenseCodesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *licenseCodesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *licenseCodesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Get return a specified license code. License codes are mirrored across all projects that have permissions to read the License Code.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licenseCodesRESTClient) Get(ctx context.Context, req *computepb.GetLicenseCodeRequest, opts ...gax.CallOption) (*computepb.LicenseCode, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenseCodes/%v", req.GetProject(), req.GetLicenseCode())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.LicenseCode{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licenseCodesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsLicenseCodeRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenseCodes/%v/testIamPermissions", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/license_codes_client_example_test.go b/compute/apiv1/license_codes_client_example_test.go
new file mode 100644
index 0000000..a0b54d3
--- /dev/null
+++ b/compute/apiv1/license_codes_client_example_test.go
@@ -0,0 +1,74 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewLicenseCodesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewLicenseCodesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleLicenseCodesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewLicenseCodesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetLicenseCodeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicenseCodesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewLicenseCodesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsLicenseCodeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/licenses_client.go b/compute/apiv1/licenses_client.go
new file mode 100644
index 0000000..f2f2ed9
--- /dev/null
+++ b/compute/apiv1/licenses_client.go
@@ -0,0 +1,539 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newLicensesClientHook clientHook
+
+// LicensesCallOptions contains the retry settings for each method of LicensesClient.
+type LicensesCallOptions struct {
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalLicensesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalLicensesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteLicenseRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetLicenseRequest, ...gax.CallOption) (*computepb.License, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyLicenseRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertLicenseRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListLicensesRequest, ...gax.CallOption) (*computepb.LicensesListResponse, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyLicenseRequest, ...gax.CallOption) (*computepb.Policy, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsLicenseRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// LicensesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Licenses API.
+type LicensesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalLicensesClient
+
+	// The call options for this service.
+	CallOptions *LicensesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *LicensesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *LicensesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *LicensesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified license.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) Delete(ctx context.Context, req *computepb.DeleteLicenseRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified License resource.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) Get(ctx context.Context, req *computepb.GetLicenseRequest, opts ...gax.CallOption) (*computepb.License, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyLicenseRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert create a License resource in the specified project.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) Insert(ctx context.Context, req *computepb.InsertLicenseRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of licenses available in the specified project. This method does not get any licenses that belong to other projects, including licenses attached to publicly-available images, like Debian 9. If you want to get a list of publicly-available licenses, use this method to make a request to the respective image project, such as debian-cloud or windows-cloud.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) List(ctx context.Context, req *computepb.ListLicensesRequest, opts ...gax.CallOption) (*computepb.LicensesListResponse, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyLicenseRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *LicensesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsLicenseRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type licensesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewLicensesRESTClient creates a new licenses rest client.
+//
+// The Licenses API.
+func NewLicensesRESTClient(ctx context.Context, opts ...option.ClientOption) (*LicensesClient, error) {
+	clientOpts := append(defaultLicensesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &licensesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &LicensesClient{internalClient: c, CallOptions: &LicensesCallOptions{}}, nil
+}
+
+func defaultLicensesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *licensesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *licensesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *licensesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified license.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) Delete(ctx context.Context, req *computepb.DeleteLicenseRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses/%v", req.GetProject(), req.GetLicense())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified License resource.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) Get(ctx context.Context, req *computepb.GetLicenseRequest, opts ...gax.CallOption) (*computepb.License, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses/%v", req.GetProject(), req.GetLicense())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.License{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyLicenseRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses/%v/getIamPolicy", req.GetProject(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert create a License resource in the specified project.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) Insert(ctx context.Context, req *computepb.InsertLicenseRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetLicenseResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of licenses available in the specified project. This method does not get any licenses that belong to other projects, including licenses attached to publicly-available images, like Debian 9. If you want to get a list of publicly-available licenses, use this method to make a request to the respective image project, such as debian-cloud or windows-cloud.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) List(ctx context.Context, req *computepb.ListLicensesRequest, opts ...gax.CallOption) (*computepb.LicensesListResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.LicensesListResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyLicenseRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses/%v/setIamPolicy", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.  Caution This resource is intended for use only by third-party partners who are creating Cloud Marketplace images.
+func (c *licensesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsLicenseRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/licenses/%v/testIamPermissions", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/licenses_client_example_test.go b/compute/apiv1/licenses_client_example_test.go
new file mode 100644
index 0000000..82f80b1
--- /dev/null
+++ b/compute/apiv1/licenses_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewLicensesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleLicensesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteLicenseRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicensesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetLicenseRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicensesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyLicenseRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicensesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertLicenseRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicensesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListLicensesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicensesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyLicenseRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleLicensesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewLicensesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsLicenseRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/machine_types_client.go b/compute/apiv1/machine_types_client.go
new file mode 100644
index 0000000..b888cab
--- /dev/null
+++ b/compute/apiv1/machine_types_client.go
@@ -0,0 +1,337 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newMachineTypesClientHook clientHook
+
+// MachineTypesCallOptions contains the retry settings for each method of MachineTypesClient.
+type MachineTypesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Get            []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalMachineTypesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalMachineTypesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListMachineTypesRequest, ...gax.CallOption) (*computepb.MachineTypeAggregatedList, error)
+	Get(context.Context, *computepb.GetMachineTypeRequest, ...gax.CallOption) (*computepb.MachineType, error)
+	List(context.Context, *computepb.ListMachineTypesRequest, ...gax.CallOption) (*computepb.MachineTypeList, error)
+}
+
+// MachineTypesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The MachineTypes API.
+type MachineTypesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalMachineTypesClient
+
+	// The call options for this service.
+	CallOptions *MachineTypesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *MachineTypesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *MachineTypesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *MachineTypesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of machine types.
+func (c *MachineTypesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListMachineTypesRequest, opts ...gax.CallOption) (*computepb.MachineTypeAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Get returns the specified machine type. Gets a list of available machine types by making a list() request.
+func (c *MachineTypesClient) Get(ctx context.Context, req *computepb.GetMachineTypeRequest, opts ...gax.CallOption) (*computepb.MachineType, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of machine types available to the specified project.
+func (c *MachineTypesClient) List(ctx context.Context, req *computepb.ListMachineTypesRequest, opts ...gax.CallOption) (*computepb.MachineTypeList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type machineTypesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewMachineTypesRESTClient creates a new machine types rest client.
+//
+// The MachineTypes API.
+func NewMachineTypesRESTClient(ctx context.Context, opts ...option.ClientOption) (*MachineTypesClient, error) {
+	clientOpts := append(defaultMachineTypesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &machineTypesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &MachineTypesClient{internalClient: c, CallOptions: &MachineTypesCallOptions{}}, nil
+}
+
+func defaultMachineTypesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *machineTypesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *machineTypesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *machineTypesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of machine types.
+func (c *machineTypesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListMachineTypesRequest, opts ...gax.CallOption) (*computepb.MachineTypeAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/machineTypes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.MachineTypeAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified machine type. Gets a list of available machine types by making a list() request.
+func (c *machineTypesRESTClient) Get(ctx context.Context, req *computepb.GetMachineTypeRequest, opts ...gax.CallOption) (*computepb.MachineType, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/machineTypes/%v", req.GetProject(), req.GetZone(), req.GetMachineType())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.MachineType{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of machine types available to the specified project.
+func (c *machineTypesRESTClient) List(ctx context.Context, req *computepb.ListMachineTypesRequest, opts ...gax.CallOption) (*computepb.MachineTypeList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/machineTypes", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.MachineTypeList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/machine_types_client_example_test.go b/compute/apiv1/machine_types_client_example_test.go
new file mode 100644
index 0000000..858b403
--- /dev/null
+++ b/compute/apiv1/machine_types_client_example_test.go
@@ -0,0 +1,93 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewMachineTypesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewMachineTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleMachineTypesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewMachineTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListMachineTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleMachineTypesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewMachineTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetMachineTypeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleMachineTypesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewMachineTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListMachineTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/network_endpoint_groups_client.go b/compute/apiv1/network_endpoint_groups_client.go
new file mode 100644
index 0000000..f9da210
--- /dev/null
+++ b/compute/apiv1/network_endpoint_groups_client.go
@@ -0,0 +1,689 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newNetworkEndpointGroupsClientHook clientHook
+
+// NetworkEndpointGroupsCallOptions contains the retry settings for each method of NetworkEndpointGroupsClient.
+type NetworkEndpointGroupsCallOptions struct {
+	AggregatedList         []gax.CallOption
+	AttachNetworkEndpoints []gax.CallOption
+	Delete                 []gax.CallOption
+	DetachNetworkEndpoints []gax.CallOption
+	Get                    []gax.CallOption
+	Insert                 []gax.CallOption
+	List                   []gax.CallOption
+	ListNetworkEndpoints   []gax.CallOption
+	TestIamPermissions     []gax.CallOption
+}
+
+// internalNetworkEndpointGroupsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalNetworkEndpointGroupsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListNetworkEndpointGroupsRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroupAggregatedList, error)
+	AttachNetworkEndpoints(context.Context, *computepb.AttachNetworkEndpointsNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DetachNetworkEndpoints(context.Context, *computepb.DetachNetworkEndpointsNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroup, error)
+	Insert(context.Context, *computepb.InsertNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListNetworkEndpointGroupsRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error)
+	ListNetworkEndpoints(context.Context, *computepb.ListNetworkEndpointsNetworkEndpointGroupsRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroupsListNetworkEndpoints, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// NetworkEndpointGroupsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The NetworkEndpointGroups API.
+type NetworkEndpointGroupsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalNetworkEndpointGroupsClient
+
+	// The call options for this service.
+	CallOptions *NetworkEndpointGroupsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *NetworkEndpointGroupsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *NetworkEndpointGroupsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *NetworkEndpointGroupsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves the list of network endpoint groups and sorts them by zone.
+func (c *NetworkEndpointGroupsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// AttachNetworkEndpoints attach a list of network endpoints to the specified network endpoint group.
+func (c *NetworkEndpointGroupsClient) AttachNetworkEndpoints(ctx context.Context, req *computepb.AttachNetworkEndpointsNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AttachNetworkEndpoints(ctx, req, opts...)
+}
+
+// Delete deletes the specified network endpoint group. The network endpoints in the NEG and the VM instances they belong to are not terminated when the NEG is deleted. Note that the NEG cannot be deleted if there are backend services referencing it.
+func (c *NetworkEndpointGroupsClient) Delete(ctx context.Context, req *computepb.DeleteNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DetachNetworkEndpoints detach a list of network endpoints from the specified network endpoint group.
+func (c *NetworkEndpointGroupsClient) DetachNetworkEndpoints(ctx context.Context, req *computepb.DetachNetworkEndpointsNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DetachNetworkEndpoints(ctx, req, opts...)
+}
+
+// Get returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request.
+func (c *NetworkEndpointGroupsClient) Get(ctx context.Context, req *computepb.GetNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroup, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a network endpoint group in the specified project using the parameters that are included in the request.
+func (c *NetworkEndpointGroupsClient) Insert(ctx context.Context, req *computepb.InsertNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of network endpoint groups that are located in the specified project and zone.
+func (c *NetworkEndpointGroupsClient) List(ctx context.Context, req *computepb.ListNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListNetworkEndpoints lists the network endpoints in the specified network endpoint group.
+func (c *NetworkEndpointGroupsClient) ListNetworkEndpoints(ctx context.Context, req *computepb.ListNetworkEndpointsNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupsListNetworkEndpoints, error) {
+	return c.internalClient.ListNetworkEndpoints(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *NetworkEndpointGroupsClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type networkEndpointGroupsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewNetworkEndpointGroupsRESTClient creates a new network endpoint groups rest client.
+//
+// The NetworkEndpointGroups API.
+func NewNetworkEndpointGroupsRESTClient(ctx context.Context, opts ...option.ClientOption) (*NetworkEndpointGroupsClient, error) {
+	clientOpts := append(defaultNetworkEndpointGroupsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &networkEndpointGroupsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &NetworkEndpointGroupsClient{internalClient: c, CallOptions: &NetworkEndpointGroupsCallOptions{}}, nil
+}
+
+func defaultNetworkEndpointGroupsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *networkEndpointGroupsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *networkEndpointGroupsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *networkEndpointGroupsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves the list of network endpoint groups and sorts them by zone.
+func (c *networkEndpointGroupsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/networkEndpointGroups", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroupAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AttachNetworkEndpoints attach a list of network endpoints to the specified network endpoint group.
+func (c *networkEndpointGroupsRESTClient) AttachNetworkEndpoints(ctx context.Context, req *computepb.AttachNetworkEndpointsNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkEndpointGroupsAttachEndpointsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups/%v/attachNetworkEndpoints", req.GetProject(), req.GetZone(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified network endpoint group. The network endpoints in the NEG and the VM instances they belong to are not terminated when the NEG is deleted. Note that the NEG cannot be deleted if there are backend services referencing it.
+func (c *networkEndpointGroupsRESTClient) Delete(ctx context.Context, req *computepb.DeleteNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups/%v", req.GetProject(), req.GetZone(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DetachNetworkEndpoints detach a list of network endpoints from the specified network endpoint group.
+func (c *networkEndpointGroupsRESTClient) DetachNetworkEndpoints(ctx context.Context, req *computepb.DetachNetworkEndpointsNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkEndpointGroupsDetachEndpointsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups/%v/detachNetworkEndpoints", req.GetProject(), req.GetZone(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request.
+func (c *networkEndpointGroupsRESTClient) Get(ctx context.Context, req *computepb.GetNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroup, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups/%v", req.GetProject(), req.GetZone(), req.GetNetworkEndpointGroup())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroup{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a network endpoint group in the specified project using the parameters that are included in the request.
+func (c *networkEndpointGroupsRESTClient) Insert(ctx context.Context, req *computepb.InsertNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkEndpointGroupResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of network endpoint groups that are located in the specified project and zone.
+func (c *networkEndpointGroupsRESTClient) List(ctx context.Context, req *computepb.ListNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroupList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListNetworkEndpoints lists the network endpoints in the specified network endpoint group.
+func (c *networkEndpointGroupsRESTClient) ListNetworkEndpoints(ctx context.Context, req *computepb.ListNetworkEndpointsNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupsListNetworkEndpoints, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkEndpointGroupsListEndpointsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups/%v/listNetworkEndpoints", req.GetProject(), req.GetZone(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroupsListNetworkEndpoints{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *networkEndpointGroupsRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/networkEndpointGroups/%v/testIamPermissions", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/network_endpoint_groups_client_example_test.go b/compute/apiv1/network_endpoint_groups_client_example_test.go
new file mode 100644
index 0000000..5c37029
--- /dev/null
+++ b/compute/apiv1/network_endpoint_groups_client_example_test.go
@@ -0,0 +1,207 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewNetworkEndpointGroupsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleNetworkEndpointGroupsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListNetworkEndpointGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_AttachNetworkEndpoints() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AttachNetworkEndpointsNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AttachNetworkEndpoints(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_DetachNetworkEndpoints() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DetachNetworkEndpointsNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DetachNetworkEndpoints(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNetworkEndpointGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_ListNetworkEndpoints() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNetworkEndpointsNetworkEndpointGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListNetworkEndpoints(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworkEndpointGroupsClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/networks_client.go b/compute/apiv1/networks_client.go
new file mode 100644
index 0000000..432e0e8
--- /dev/null
+++ b/compute/apiv1/networks_client.go
@@ -0,0 +1,797 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newNetworksClientHook clientHook
+
+// NetworksCallOptions contains the retry settings for each method of NetworksClient.
+type NetworksCallOptions struct {
+	AddPeering            []gax.CallOption
+	Delete                []gax.CallOption
+	Get                   []gax.CallOption
+	GetEffectiveFirewalls []gax.CallOption
+	Insert                []gax.CallOption
+	List                  []gax.CallOption
+	ListPeeringRoutes     []gax.CallOption
+	Patch                 []gax.CallOption
+	RemovePeering         []gax.CallOption
+	SwitchToCustomMode    []gax.CallOption
+	UpdatePeering         []gax.CallOption
+}
+
+// internalNetworksClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalNetworksClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddPeering(context.Context, *computepb.AddPeeringNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetNetworkRequest, ...gax.CallOption) (*computepb.Network, error)
+	GetEffectiveFirewalls(context.Context, *computepb.GetEffectiveFirewallsNetworkRequest, ...gax.CallOption) (*computepb.NetworksGetEffectiveFirewallsResponse, error)
+	Insert(context.Context, *computepb.InsertNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListNetworksRequest, ...gax.CallOption) (*computepb.NetworkList, error)
+	ListPeeringRoutes(context.Context, *computepb.ListPeeringRoutesNetworksRequest, ...gax.CallOption) (*computepb.ExchangedPeeringRoutesList, error)
+	Patch(context.Context, *computepb.PatchNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RemovePeering(context.Context, *computepb.RemovePeeringNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SwitchToCustomMode(context.Context, *computepb.SwitchToCustomModeNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdatePeering(context.Context, *computepb.UpdatePeeringNetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// NetworksClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Networks API.
+type NetworksClient struct {
+	// The internal transport-dependent client.
+	internalClient internalNetworksClient
+
+	// The call options for this service.
+	CallOptions *NetworksCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *NetworksClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *NetworksClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *NetworksClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddPeering adds a peering to the specified network.
+func (c *NetworksClient) AddPeering(ctx context.Context, req *computepb.AddPeeringNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddPeering(ctx, req, opts...)
+}
+
+// Delete deletes the specified network.
+func (c *NetworksClient) Delete(ctx context.Context, req *computepb.DeleteNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified network. Gets a list of available networks by making a list() request.
+func (c *NetworksClient) Get(ctx context.Context, req *computepb.GetNetworkRequest, opts ...gax.CallOption) (*computepb.Network, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetEffectiveFirewalls returns the effective firewalls on a given network.
+func (c *NetworksClient) GetEffectiveFirewalls(ctx context.Context, req *computepb.GetEffectiveFirewallsNetworkRequest, opts ...gax.CallOption) (*computepb.NetworksGetEffectiveFirewallsResponse, error) {
+	return c.internalClient.GetEffectiveFirewalls(ctx, req, opts...)
+}
+
+// Insert creates a network in the specified project using the data included in the request.
+func (c *NetworksClient) Insert(ctx context.Context, req *computepb.InsertNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of networks available to the specified project.
+func (c *NetworksClient) List(ctx context.Context, req *computepb.ListNetworksRequest, opts ...gax.CallOption) (*computepb.NetworkList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListPeeringRoutes lists the peering routes exchanged over peering connection.
+func (c *NetworksClient) ListPeeringRoutes(ctx context.Context, req *computepb.ListPeeringRoutesNetworksRequest, opts ...gax.CallOption) (*computepb.ExchangedPeeringRoutesList, error) {
+	return c.internalClient.ListPeeringRoutes(ctx, req, opts...)
+}
+
+// Patch patches the specified network with the data included in the request. Only the following fields can be modified: routingConfig.routingMode.
+func (c *NetworksClient) Patch(ctx context.Context, req *computepb.PatchNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// RemovePeering removes a peering from the specified network.
+func (c *NetworksClient) RemovePeering(ctx context.Context, req *computepb.RemovePeeringNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemovePeering(ctx, req, opts...)
+}
+
+// SwitchToCustomMode switches the network mode from auto subnet mode to custom subnet mode.
+func (c *NetworksClient) SwitchToCustomMode(ctx context.Context, req *computepb.SwitchToCustomModeNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SwitchToCustomMode(ctx, req, opts...)
+}
+
+// UpdatePeering updates the specified network peering with the data included in the request Only the following fields can be modified: NetworkPeering.export_custom_routes, and NetworkPeering.import_custom_routes
+func (c *NetworksClient) UpdatePeering(ctx context.Context, req *computepb.UpdatePeeringNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdatePeering(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type networksRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewNetworksRESTClient creates a new networks rest client.
+//
+// The Networks API.
+func NewNetworksRESTClient(ctx context.Context, opts ...option.ClientOption) (*NetworksClient, error) {
+	clientOpts := append(defaultNetworksRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &networksRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &NetworksClient{internalClient: c, CallOptions: &NetworksCallOptions{}}, nil
+}
+
+func defaultNetworksRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *networksRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *networksRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *networksRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddPeering adds a peering to the specified network.
+func (c *networksRESTClient) AddPeering(ctx context.Context, req *computepb.AddPeeringNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworksAddPeeringRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v/addPeering", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified network.
+func (c *networksRESTClient) Delete(ctx context.Context, req *computepb.DeleteNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified network. Gets a list of available networks by making a list() request.
+func (c *networksRESTClient) Get(ctx context.Context, req *computepb.GetNetworkRequest, opts ...gax.CallOption) (*computepb.Network, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v", req.GetProject(), req.GetNetwork())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Network{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetEffectiveFirewalls returns the effective firewalls on a given network.
+func (c *networksRESTClient) GetEffectiveFirewalls(ctx context.Context, req *computepb.GetEffectiveFirewallsNetworkRequest, opts ...gax.CallOption) (*computepb.NetworksGetEffectiveFirewallsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v/getEffectiveFirewalls", req.GetProject(), req.GetNetwork())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworksGetEffectiveFirewallsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a network in the specified project using the data included in the request.
+func (c *networksRESTClient) Insert(ctx context.Context, req *computepb.InsertNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of networks available to the specified project.
+func (c *networksRESTClient) List(ctx context.Context, req *computepb.ListNetworksRequest, opts ...gax.CallOption) (*computepb.NetworkList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListPeeringRoutes lists the peering routes exchanged over peering connection.
+func (c *networksRESTClient) ListPeeringRoutes(ctx context.Context, req *computepb.ListPeeringRoutesNetworksRequest, opts ...gax.CallOption) (*computepb.ExchangedPeeringRoutesList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v/listPeeringRoutes", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.Direction != nil {
+		params.Add("direction", fmt.Sprintf("%v", req.GetDirection()))
+	}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.PeeringName != nil {
+		params.Add("peeringName", fmt.Sprintf("%v", req.GetPeeringName()))
+	}
+	if req != nil && req.Region != nil {
+		params.Add("region", fmt.Sprintf("%v", req.GetRegion()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ExchangedPeeringRoutesList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified network with the data included in the request. Only the following fields can be modified: routingConfig.routingMode.
+func (c *networksRESTClient) Patch(ctx context.Context, req *computepb.PatchNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemovePeering removes a peering from the specified network.
+func (c *networksRESTClient) RemovePeering(ctx context.Context, req *computepb.RemovePeeringNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworksRemovePeeringRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v/removePeering", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SwitchToCustomMode switches the network mode from auto subnet mode to custom subnet mode.
+func (c *networksRESTClient) SwitchToCustomMode(ctx context.Context, req *computepb.SwitchToCustomModeNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v/switchToCustomMode", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdatePeering updates the specified network peering with the data included in the request Only the following fields can be modified: NetworkPeering.export_custom_routes, and NetworkPeering.import_custom_routes
+func (c *networksRESTClient) UpdatePeering(ctx context.Context, req *computepb.UpdatePeeringNetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworksUpdatePeeringRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/networks/%v/updatePeering", req.GetProject(), req.GetNetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/networks_client_example_test.go b/compute/apiv1/networks_client_example_test.go
new file mode 100644
index 0000000..74578fd
--- /dev/null
+++ b/compute/apiv1/networks_client_example_test.go
@@ -0,0 +1,245 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewNetworksRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleNetworksClient_AddPeering() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddPeeringNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddPeering(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_GetEffectiveFirewalls() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetEffectiveFirewallsNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetEffectiveFirewalls(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNetworksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_ListPeeringRoutes() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPeeringRoutesNetworksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListPeeringRoutes(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_RemovePeering() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemovePeeringNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemovePeering(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_SwitchToCustomMode() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SwitchToCustomModeNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SwitchToCustomMode(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNetworksClient_UpdatePeering() {
+	ctx := context.Background()
+	c, err := compute.NewNetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdatePeeringNetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdatePeering(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/node_groups_client.go b/compute/apiv1/node_groups_client.go
new file mode 100644
index 0000000..6456388
--- /dev/null
+++ b/compute/apiv1/node_groups_client.go
@@ -0,0 +1,915 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newNodeGroupsClientHook clientHook
+
+// NodeGroupsCallOptions contains the retry settings for each method of NodeGroupsClient.
+type NodeGroupsCallOptions struct {
+	AddNodes           []gax.CallOption
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	DeleteNodes        []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	ListNodes          []gax.CallOption
+	Patch              []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	SetNodeTemplate    []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalNodeGroupsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalNodeGroupsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddNodes(context.Context, *computepb.AddNodesNodeGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListNodeGroupsRequest, ...gax.CallOption) (*computepb.NodeGroupAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteNodeGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeleteNodes(context.Context, *computepb.DeleteNodesNodeGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetNodeGroupRequest, ...gax.CallOption) (*computepb.NodeGroup, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyNodeGroupRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertNodeGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListNodeGroupsRequest, ...gax.CallOption) (*computepb.NodeGroupList, error)
+	ListNodes(context.Context, *computepb.ListNodesNodeGroupsRequest, ...gax.CallOption) (*computepb.NodeGroupsListNodes, error)
+	Patch(context.Context, *computepb.PatchNodeGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyNodeGroupRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetNodeTemplate(context.Context, *computepb.SetNodeTemplateNodeGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsNodeGroupRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// NodeGroupsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The NodeGroups API.
+type NodeGroupsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalNodeGroupsClient
+
+	// The call options for this service.
+	CallOptions *NodeGroupsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *NodeGroupsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *NodeGroupsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *NodeGroupsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddNodes adds specified number of nodes to the node group.
+func (c *NodeGroupsClient) AddNodes(ctx context.Context, req *computepb.AddNodesNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddNodes(ctx, req, opts...)
+}
+
+// AggregatedList retrieves an aggregated list of node groups. Note: use nodeGroups.listNodes for more details about each group.
+func (c *NodeGroupsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNodeGroupsRequest, opts ...gax.CallOption) (*computepb.NodeGroupAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified NodeGroup resource.
+func (c *NodeGroupsClient) Delete(ctx context.Context, req *computepb.DeleteNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DeleteNodes deletes specified nodes from the node group.
+func (c *NodeGroupsClient) DeleteNodes(ctx context.Context, req *computepb.DeleteNodesNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeleteNodes(ctx, req, opts...)
+}
+
+// Get returns the specified NodeGroup. Get a list of available NodeGroups by making a list() request. Note: the “nodes” field should not be used. Use nodeGroups.listNodes instead.
+func (c *NodeGroupsClient) Get(ctx context.Context, req *computepb.GetNodeGroupRequest, opts ...gax.CallOption) (*computepb.NodeGroup, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *NodeGroupsClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyNodeGroupRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a NodeGroup resource in the specified project using the data included in the request.
+func (c *NodeGroupsClient) Insert(ctx context.Context, req *computepb.InsertNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of node groups available to the specified project. Note: use nodeGroups.listNodes for more details about each group.
+func (c *NodeGroupsClient) List(ctx context.Context, req *computepb.ListNodeGroupsRequest, opts ...gax.CallOption) (*computepb.NodeGroupList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListNodes lists nodes in the node group.
+func (c *NodeGroupsClient) ListNodes(ctx context.Context, req *computepb.ListNodesNodeGroupsRequest, opts ...gax.CallOption) (*computepb.NodeGroupsListNodes, error) {
+	return c.internalClient.ListNodes(ctx, req, opts...)
+}
+
+// Patch updates the specified node group.
+func (c *NodeGroupsClient) Patch(ctx context.Context, req *computepb.PatchNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *NodeGroupsClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyNodeGroupRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetNodeTemplate updates the node template of the node group.
+func (c *NodeGroupsClient) SetNodeTemplate(ctx context.Context, req *computepb.SetNodeTemplateNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetNodeTemplate(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *NodeGroupsClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsNodeGroupRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type nodeGroupsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewNodeGroupsRESTClient creates a new node groups rest client.
+//
+// The NodeGroups API.
+func NewNodeGroupsRESTClient(ctx context.Context, opts ...option.ClientOption) (*NodeGroupsClient, error) {
+	clientOpts := append(defaultNodeGroupsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &nodeGroupsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &NodeGroupsClient{internalClient: c, CallOptions: &NodeGroupsCallOptions{}}, nil
+}
+
+func defaultNodeGroupsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *nodeGroupsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *nodeGroupsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *nodeGroupsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddNodes adds specified number of nodes to the node group.
+func (c *nodeGroupsRESTClient) AddNodes(ctx context.Context, req *computepb.AddNodesNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNodeGroupsAddNodesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/addNodes", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves an aggregated list of node groups. Note: use nodeGroups.listNodes for more details about each group.
+func (c *nodeGroupsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNodeGroupsRequest, opts ...gax.CallOption) (*computepb.NodeGroupAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/nodeGroups", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeGroupAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified NodeGroup resource.
+func (c *nodeGroupsRESTClient) Delete(ctx context.Context, req *computepb.DeleteNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeleteNodes deletes specified nodes from the node group.
+func (c *nodeGroupsRESTClient) DeleteNodes(ctx context.Context, req *computepb.DeleteNodesNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNodeGroupsDeleteNodesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/deleteNodes", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified NodeGroup. Get a list of available NodeGroups by making a list() request. Note: the “nodes” field should not be used. Use nodeGroups.listNodes instead.
+func (c *nodeGroupsRESTClient) Get(ctx context.Context, req *computepb.GetNodeGroupRequest, opts ...gax.CallOption) (*computepb.NodeGroup, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeGroup{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *nodeGroupsRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyNodeGroupRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/getIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a NodeGroup resource in the specified project using the data included in the request.
+func (c *nodeGroupsRESTClient) Insert(ctx context.Context, req *computepb.InsertNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNodeGroupResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req.GetInitialNodeCount() != 0 {
+		params.Add("initialNodeCount", fmt.Sprintf("%v", req.GetInitialNodeCount()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of node groups available to the specified project. Note: use nodeGroups.listNodes for more details about each group.
+func (c *nodeGroupsRESTClient) List(ctx context.Context, req *computepb.ListNodeGroupsRequest, opts ...gax.CallOption) (*computepb.NodeGroupList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeGroupList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListNodes lists nodes in the node group.
+func (c *nodeGroupsRESTClient) ListNodes(ctx context.Context, req *computepb.ListNodesNodeGroupsRequest, opts ...gax.CallOption) (*computepb.NodeGroupsListNodes, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/listNodes", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeGroupsListNodes{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified node group.
+func (c *nodeGroupsRESTClient) Patch(ctx context.Context, req *computepb.PatchNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNodeGroupResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *nodeGroupsRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyNodeGroupRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetZoneSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/setIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetNodeTemplate updates the node template of the node group.
+func (c *nodeGroupsRESTClient) SetNodeTemplate(ctx context.Context, req *computepb.SetNodeTemplateNodeGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNodeGroupsSetNodeTemplateRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/setNodeTemplate", req.GetProject(), req.GetZone(), req.GetNodeGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *nodeGroupsRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsNodeGroupRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeGroups/%v/testIamPermissions", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/node_groups_client_example_test.go b/compute/apiv1/node_groups_client_example_test.go
new file mode 100644
index 0000000..8cb69f9
--- /dev/null
+++ b/compute/apiv1/node_groups_client_example_test.go
@@ -0,0 +1,283 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewNodeGroupsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleNodeGroupsClient_AddNodes() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddNodesNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddNodes(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListNodeGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_DeleteNodes() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteNodesNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeleteNodes(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNodeGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_ListNodes() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNodesNodeGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListNodes(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_SetNodeTemplate() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetNodeTemplateNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetNodeTemplate(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeGroupsClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewNodeGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsNodeGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/node_templates_client.go b/compute/apiv1/node_templates_client.go
new file mode 100644
index 0000000..eebf6d2
--- /dev/null
+++ b/compute/apiv1/node_templates_client.go
@@ -0,0 +1,611 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newNodeTemplatesClientHook clientHook
+
+// NodeTemplatesCallOptions contains the retry settings for each method of NodeTemplatesClient.
+type NodeTemplatesCallOptions struct {
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalNodeTemplatesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalNodeTemplatesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListNodeTemplatesRequest, ...gax.CallOption) (*computepb.NodeTemplateAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteNodeTemplateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetNodeTemplateRequest, ...gax.CallOption) (*computepb.NodeTemplate, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyNodeTemplateRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertNodeTemplateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListNodeTemplatesRequest, ...gax.CallOption) (*computepb.NodeTemplateList, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyNodeTemplateRequest, ...gax.CallOption) (*computepb.Policy, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsNodeTemplateRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// NodeTemplatesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The NodeTemplates API.
+type NodeTemplatesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalNodeTemplatesClient
+
+	// The call options for this service.
+	CallOptions *NodeTemplatesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *NodeTemplatesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *NodeTemplatesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *NodeTemplatesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of node templates.
+func (c *NodeTemplatesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNodeTemplatesRequest, opts ...gax.CallOption) (*computepb.NodeTemplateAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified NodeTemplate resource.
+func (c *NodeTemplatesClient) Delete(ctx context.Context, req *computepb.DeleteNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified node template. Gets a list of available node templates by making a list() request.
+func (c *NodeTemplatesClient) Get(ctx context.Context, req *computepb.GetNodeTemplateRequest, opts ...gax.CallOption) (*computepb.NodeTemplate, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *NodeTemplatesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a NodeTemplate resource in the specified project using the data included in the request.
+func (c *NodeTemplatesClient) Insert(ctx context.Context, req *computepb.InsertNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of node templates available to the specified project.
+func (c *NodeTemplatesClient) List(ctx context.Context, req *computepb.ListNodeTemplatesRequest, opts ...gax.CallOption) (*computepb.NodeTemplateList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *NodeTemplatesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *NodeTemplatesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsNodeTemplateRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type nodeTemplatesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewNodeTemplatesRESTClient creates a new node templates rest client.
+//
+// The NodeTemplates API.
+func NewNodeTemplatesRESTClient(ctx context.Context, opts ...option.ClientOption) (*NodeTemplatesClient, error) {
+	clientOpts := append(defaultNodeTemplatesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &nodeTemplatesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &NodeTemplatesClient{internalClient: c, CallOptions: &NodeTemplatesCallOptions{}}, nil
+}
+
+func defaultNodeTemplatesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *nodeTemplatesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *nodeTemplatesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *nodeTemplatesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of node templates.
+func (c *nodeTemplatesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNodeTemplatesRequest, opts ...gax.CallOption) (*computepb.NodeTemplateAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/nodeTemplates", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeTemplateAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified NodeTemplate resource.
+func (c *nodeTemplatesRESTClient) Delete(ctx context.Context, req *computepb.DeleteNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates/%v", req.GetProject(), req.GetRegion(), req.GetNodeTemplate())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified node template. Gets a list of available node templates by making a list() request.
+func (c *nodeTemplatesRESTClient) Get(ctx context.Context, req *computepb.GetNodeTemplateRequest, opts ...gax.CallOption) (*computepb.NodeTemplate, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates/%v", req.GetProject(), req.GetRegion(), req.GetNodeTemplate())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeTemplate{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *nodeTemplatesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates/%v/getIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a NodeTemplate resource in the specified project using the data included in the request.
+func (c *nodeTemplatesRESTClient) Insert(ctx context.Context, req *computepb.InsertNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNodeTemplateResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of node templates available to the specified project.
+func (c *nodeTemplatesRESTClient) List(ctx context.Context, req *computepb.ListNodeTemplatesRequest, opts ...gax.CallOption) (*computepb.NodeTemplateList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeTemplateList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *nodeTemplatesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyNodeTemplateRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates/%v/setIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *nodeTemplatesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsNodeTemplateRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/nodeTemplates/%v/testIamPermissions", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/node_templates_client_example_test.go b/compute/apiv1/node_templates_client_example_test.go
new file mode 100644
index 0000000..e589d2e
--- /dev/null
+++ b/compute/apiv1/node_templates_client_example_test.go
@@ -0,0 +1,188 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewNodeTemplatesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleNodeTemplatesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListNodeTemplatesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteNodeTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetNodeTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyNodeTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertNodeTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNodeTemplatesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyNodeTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTemplatesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTemplatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsNodeTemplateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/node_types_client.go b/compute/apiv1/node_types_client.go
new file mode 100644
index 0000000..5c72753
--- /dev/null
+++ b/compute/apiv1/node_types_client.go
@@ -0,0 +1,337 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newNodeTypesClientHook clientHook
+
+// NodeTypesCallOptions contains the retry settings for each method of NodeTypesClient.
+type NodeTypesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Get            []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalNodeTypesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalNodeTypesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListNodeTypesRequest, ...gax.CallOption) (*computepb.NodeTypeAggregatedList, error)
+	Get(context.Context, *computepb.GetNodeTypeRequest, ...gax.CallOption) (*computepb.NodeType, error)
+	List(context.Context, *computepb.ListNodeTypesRequest, ...gax.CallOption) (*computepb.NodeTypeList, error)
+}
+
+// NodeTypesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The NodeTypes API.
+type NodeTypesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalNodeTypesClient
+
+	// The call options for this service.
+	CallOptions *NodeTypesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *NodeTypesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *NodeTypesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *NodeTypesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of node types.
+func (c *NodeTypesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNodeTypesRequest, opts ...gax.CallOption) (*computepb.NodeTypeAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Get returns the specified node type. Gets a list of available node types by making a list() request.
+func (c *NodeTypesClient) Get(ctx context.Context, req *computepb.GetNodeTypeRequest, opts ...gax.CallOption) (*computepb.NodeType, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of node types available to the specified project.
+func (c *NodeTypesClient) List(ctx context.Context, req *computepb.ListNodeTypesRequest, opts ...gax.CallOption) (*computepb.NodeTypeList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type nodeTypesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewNodeTypesRESTClient creates a new node types rest client.
+//
+// The NodeTypes API.
+func NewNodeTypesRESTClient(ctx context.Context, opts ...option.ClientOption) (*NodeTypesClient, error) {
+	clientOpts := append(defaultNodeTypesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &nodeTypesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &NodeTypesClient{internalClient: c, CallOptions: &NodeTypesCallOptions{}}, nil
+}
+
+func defaultNodeTypesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *nodeTypesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *nodeTypesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *nodeTypesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of node types.
+func (c *nodeTypesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListNodeTypesRequest, opts ...gax.CallOption) (*computepb.NodeTypeAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/nodeTypes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeTypeAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified node type. Gets a list of available node types by making a list() request.
+func (c *nodeTypesRESTClient) Get(ctx context.Context, req *computepb.GetNodeTypeRequest, opts ...gax.CallOption) (*computepb.NodeType, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeTypes/%v", req.GetProject(), req.GetZone(), req.GetNodeType())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeType{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of node types available to the specified project.
+func (c *nodeTypesRESTClient) List(ctx context.Context, req *computepb.ListNodeTypesRequest, opts ...gax.CallOption) (*computepb.NodeTypeList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/nodeTypes", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NodeTypeList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/node_types_client_example_test.go b/compute/apiv1/node_types_client_example_test.go
new file mode 100644
index 0000000..9f18446
--- /dev/null
+++ b/compute/apiv1/node_types_client_example_test.go
@@ -0,0 +1,93 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewNodeTypesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleNodeTypesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListNodeTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTypesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetNodeTypeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleNodeTypesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewNodeTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListNodeTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/packet_mirrorings_client.go b/compute/apiv1/packet_mirrorings_client.go
new file mode 100644
index 0000000..2ddda96
--- /dev/null
+++ b/compute/apiv1/packet_mirrorings_client.go
@@ -0,0 +1,561 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newPacketMirroringsClientHook clientHook
+
+// PacketMirroringsCallOptions contains the retry settings for each method of PacketMirroringsClient.
+type PacketMirroringsCallOptions struct {
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	Patch              []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalPacketMirroringsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalPacketMirroringsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListPacketMirroringsRequest, ...gax.CallOption) (*computepb.PacketMirroringAggregatedList, error)
+	Delete(context.Context, *computepb.DeletePacketMirroringRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetPacketMirroringRequest, ...gax.CallOption) (*computepb.PacketMirroring, error)
+	Insert(context.Context, *computepb.InsertPacketMirroringRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListPacketMirroringsRequest, ...gax.CallOption) (*computepb.PacketMirroringList, error)
+	Patch(context.Context, *computepb.PatchPacketMirroringRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsPacketMirroringRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// PacketMirroringsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The PacketMirrorings API.
+type PacketMirroringsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalPacketMirroringsClient
+
+	// The call options for this service.
+	CallOptions *PacketMirroringsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *PacketMirroringsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *PacketMirroringsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *PacketMirroringsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of packetMirrorings.
+func (c *PacketMirroringsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListPacketMirroringsRequest, opts ...gax.CallOption) (*computepb.PacketMirroringAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified PacketMirroring resource.
+func (c *PacketMirroringsClient) Delete(ctx context.Context, req *computepb.DeletePacketMirroringRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified PacketMirroring resource.
+func (c *PacketMirroringsClient) Get(ctx context.Context, req *computepb.GetPacketMirroringRequest, opts ...gax.CallOption) (*computepb.PacketMirroring, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a PacketMirroring resource in the specified project and region using the data included in the request.
+func (c *PacketMirroringsClient) Insert(ctx context.Context, req *computepb.InsertPacketMirroringRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of PacketMirroring resources available to the specified project and region.
+func (c *PacketMirroringsClient) List(ctx context.Context, req *computepb.ListPacketMirroringsRequest, opts ...gax.CallOption) (*computepb.PacketMirroringList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified PacketMirroring resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *PacketMirroringsClient) Patch(ctx context.Context, req *computepb.PatchPacketMirroringRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *PacketMirroringsClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsPacketMirroringRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type packetMirroringsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewPacketMirroringsRESTClient creates a new packet mirrorings rest client.
+//
+// The PacketMirrorings API.
+func NewPacketMirroringsRESTClient(ctx context.Context, opts ...option.ClientOption) (*PacketMirroringsClient, error) {
+	clientOpts := append(defaultPacketMirroringsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &packetMirroringsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &PacketMirroringsClient{internalClient: c, CallOptions: &PacketMirroringsCallOptions{}}, nil
+}
+
+func defaultPacketMirroringsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *packetMirroringsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *packetMirroringsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *packetMirroringsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of packetMirrorings.
+func (c *packetMirroringsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListPacketMirroringsRequest, opts ...gax.CallOption) (*computepb.PacketMirroringAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/packetMirrorings", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PacketMirroringAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified PacketMirroring resource.
+func (c *packetMirroringsRESTClient) Delete(ctx context.Context, req *computepb.DeletePacketMirroringRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/packetMirrorings/%v", req.GetProject(), req.GetRegion(), req.GetPacketMirroring())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified PacketMirroring resource.
+func (c *packetMirroringsRESTClient) Get(ctx context.Context, req *computepb.GetPacketMirroringRequest, opts ...gax.CallOption) (*computepb.PacketMirroring, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/packetMirrorings/%v", req.GetProject(), req.GetRegion(), req.GetPacketMirroring())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PacketMirroring{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a PacketMirroring resource in the specified project and region using the data included in the request.
+func (c *packetMirroringsRESTClient) Insert(ctx context.Context, req *computepb.InsertPacketMirroringRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPacketMirroringResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/packetMirrorings", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of PacketMirroring resources available to the specified project and region.
+func (c *packetMirroringsRESTClient) List(ctx context.Context, req *computepb.ListPacketMirroringsRequest, opts ...gax.CallOption) (*computepb.PacketMirroringList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/packetMirrorings", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PacketMirroringList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified PacketMirroring resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *packetMirroringsRESTClient) Patch(ctx context.Context, req *computepb.PatchPacketMirroringRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPacketMirroringResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/packetMirrorings/%v", req.GetProject(), req.GetRegion(), req.GetPacketMirroring())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *packetMirroringsRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsPacketMirroringRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/packetMirrorings/%v/testIamPermissions", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/packet_mirrorings_client_example_test.go b/compute/apiv1/packet_mirrorings_client_example_test.go
new file mode 100644
index 0000000..6ce5c37
--- /dev/null
+++ b/compute/apiv1/packet_mirrorings_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewPacketMirroringsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExamplePacketMirroringsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListPacketMirroringsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePacketMirroringsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeletePacketMirroringRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePacketMirroringsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetPacketMirroringRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePacketMirroringsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertPacketMirroringRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePacketMirroringsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPacketMirroringsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePacketMirroringsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchPacketMirroringRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePacketMirroringsClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewPacketMirroringsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsPacketMirroringRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/projects_client.go b/compute/apiv1/projects_client.go
new file mode 100644
index 0000000..03d1aa4
--- /dev/null
+++ b/compute/apiv1/projects_client.go
@@ -0,0 +1,905 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newProjectsClientHook clientHook
+
+// ProjectsCallOptions contains the retry settings for each method of ProjectsClient.
+type ProjectsCallOptions struct {
+	DisableXpnHost            []gax.CallOption
+	DisableXpnResource        []gax.CallOption
+	EnableXpnHost             []gax.CallOption
+	EnableXpnResource         []gax.CallOption
+	Get                       []gax.CallOption
+	GetXpnHost                []gax.CallOption
+	GetXpnResources           []gax.CallOption
+	ListXpnHosts              []gax.CallOption
+	MoveDisk                  []gax.CallOption
+	MoveInstance              []gax.CallOption
+	SetCommonInstanceMetadata []gax.CallOption
+	SetDefaultNetworkTier     []gax.CallOption
+	SetUsageExportBucket      []gax.CallOption
+}
+
+// internalProjectsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalProjectsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	DisableXpnHost(context.Context, *computepb.DisableXpnHostProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DisableXpnResource(context.Context, *computepb.DisableXpnResourceProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	EnableXpnHost(context.Context, *computepb.EnableXpnHostProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	EnableXpnResource(context.Context, *computepb.EnableXpnResourceProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetProjectRequest, ...gax.CallOption) (*computepb.Project, error)
+	GetXpnHost(context.Context, *computepb.GetXpnHostProjectRequest, ...gax.CallOption) (*computepb.Project, error)
+	GetXpnResources(context.Context, *computepb.GetXpnResourcesProjectsRequest, ...gax.CallOption) (*computepb.ProjectsGetXpnResources, error)
+	ListXpnHosts(context.Context, *computepb.ListXpnHostsProjectsRequest, ...gax.CallOption) (*computepb.XpnHostList, error)
+	MoveDisk(context.Context, *computepb.MoveDiskProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	MoveInstance(context.Context, *computepb.MoveInstanceProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetCommonInstanceMetadata(context.Context, *computepb.SetCommonInstanceMetadataProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetDefaultNetworkTier(context.Context, *computepb.SetDefaultNetworkTierProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetUsageExportBucket(context.Context, *computepb.SetUsageExportBucketProjectRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// ProjectsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Projects API.
+type ProjectsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalProjectsClient
+
+	// The call options for this service.
+	CallOptions *ProjectsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ProjectsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ProjectsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ProjectsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// DisableXpnHost disable this project as a shared VPC host project.
+func (c *ProjectsClient) DisableXpnHost(ctx context.Context, req *computepb.DisableXpnHostProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DisableXpnHost(ctx, req, opts...)
+}
+
+// DisableXpnResource disable a service resource (also known as service project) associated with this host project.
+func (c *ProjectsClient) DisableXpnResource(ctx context.Context, req *computepb.DisableXpnResourceProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DisableXpnResource(ctx, req, opts...)
+}
+
+// EnableXpnHost enable this project as a shared VPC host project.
+func (c *ProjectsClient) EnableXpnHost(ctx context.Context, req *computepb.EnableXpnHostProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.EnableXpnHost(ctx, req, opts...)
+}
+
+// EnableXpnResource enable service resource (a.k.a service project) for a host project, so that subnets in the host project can be used by instances in the service project.
+func (c *ProjectsClient) EnableXpnResource(ctx context.Context, req *computepb.EnableXpnResourceProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.EnableXpnResource(ctx, req, opts...)
+}
+
+// Get returns the specified Project resource.
+func (c *ProjectsClient) Get(ctx context.Context, req *computepb.GetProjectRequest, opts ...gax.CallOption) (*computepb.Project, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetXpnHost gets the shared VPC host project that this project links to. May be empty if no link exists.
+func (c *ProjectsClient) GetXpnHost(ctx context.Context, req *computepb.GetXpnHostProjectRequest, opts ...gax.CallOption) (*computepb.Project, error) {
+	return c.internalClient.GetXpnHost(ctx, req, opts...)
+}
+
+// GetXpnResources gets service resources (a.k.a service project) associated with this host project.
+func (c *ProjectsClient) GetXpnResources(ctx context.Context, req *computepb.GetXpnResourcesProjectsRequest, opts ...gax.CallOption) (*computepb.ProjectsGetXpnResources, error) {
+	return c.internalClient.GetXpnResources(ctx, req, opts...)
+}
+
+// ListXpnHosts lists all shared VPC host projects visible to the user in an organization.
+func (c *ProjectsClient) ListXpnHosts(ctx context.Context, req *computepb.ListXpnHostsProjectsRequest, opts ...gax.CallOption) (*computepb.XpnHostList, error) {
+	return c.internalClient.ListXpnHosts(ctx, req, opts...)
+}
+
+// MoveDisk moves a persistent disk from one zone to another.
+func (c *ProjectsClient) MoveDisk(ctx context.Context, req *computepb.MoveDiskProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.MoveDisk(ctx, req, opts...)
+}
+
+// MoveInstance moves an instance and its attached persistent disks from one zone to another.
+func (c *ProjectsClient) MoveInstance(ctx context.Context, req *computepb.MoveInstanceProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.MoveInstance(ctx, req, opts...)
+}
+
+// SetCommonInstanceMetadata sets metadata common to all instances within the specified project using the data included in the request.
+func (c *ProjectsClient) SetCommonInstanceMetadata(ctx context.Context, req *computepb.SetCommonInstanceMetadataProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetCommonInstanceMetadata(ctx, req, opts...)
+}
+
+// SetDefaultNetworkTier sets the default network tier of the project. The default network tier is used when an address/forwardingRule/instance is created without specifying the network tier field.
+func (c *ProjectsClient) SetDefaultNetworkTier(ctx context.Context, req *computepb.SetDefaultNetworkTierProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetDefaultNetworkTier(ctx, req, opts...)
+}
+
+// SetUsageExportBucket enables the usage export feature and sets the usage export bucket where reports are stored. If you provide an empty request body using this method, the usage export feature will be disabled.
+func (c *ProjectsClient) SetUsageExportBucket(ctx context.Context, req *computepb.SetUsageExportBucketProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetUsageExportBucket(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type projectsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewProjectsRESTClient creates a new projects rest client.
+//
+// The Projects API.
+func NewProjectsRESTClient(ctx context.Context, opts ...option.ClientOption) (*ProjectsClient, error) {
+	clientOpts := append(defaultProjectsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &projectsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ProjectsClient{internalClient: c, CallOptions: &ProjectsCallOptions{}}, nil
+}
+
+func defaultProjectsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *projectsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *projectsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *projectsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// DisableXpnHost disable this project as a shared VPC host project.
+func (c *projectsRESTClient) DisableXpnHost(ctx context.Context, req *computepb.DisableXpnHostProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/disableXpnHost", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DisableXpnResource disable a service resource (also known as service project) associated with this host project.
+func (c *projectsRESTClient) DisableXpnResource(ctx context.Context, req *computepb.DisableXpnResourceProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetProjectsDisableXpnResourceRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/disableXpnResource", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// EnableXpnHost enable this project as a shared VPC host project.
+func (c *projectsRESTClient) EnableXpnHost(ctx context.Context, req *computepb.EnableXpnHostProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/enableXpnHost", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// EnableXpnResource enable service resource (a.k.a service project) for a host project, so that subnets in the host project can be used by instances in the service project.
+func (c *projectsRESTClient) EnableXpnResource(ctx context.Context, req *computepb.EnableXpnResourceProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetProjectsEnableXpnResourceRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/enableXpnResource", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified Project resource.
+func (c *projectsRESTClient) Get(ctx context.Context, req *computepb.GetProjectRequest, opts ...gax.CallOption) (*computepb.Project, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v", req.GetProject())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Project{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetXpnHost gets the shared VPC host project that this project links to. May be empty if no link exists.
+func (c *projectsRESTClient) GetXpnHost(ctx context.Context, req *computepb.GetXpnHostProjectRequest, opts ...gax.CallOption) (*computepb.Project, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/getXpnHost", req.GetProject())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Project{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetXpnResources gets service resources (a.k.a service project) associated with this host project.
+func (c *projectsRESTClient) GetXpnResources(ctx context.Context, req *computepb.GetXpnResourcesProjectsRequest, opts ...gax.CallOption) (*computepb.ProjectsGetXpnResources, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/getXpnResources", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ProjectsGetXpnResources{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListXpnHosts lists all shared VPC host projects visible to the user in an organization.
+func (c *projectsRESTClient) ListXpnHosts(ctx context.Context, req *computepb.ListXpnHostsProjectsRequest, opts ...gax.CallOption) (*computepb.XpnHostList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetProjectsListXpnHostsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/listXpnHosts", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.XpnHostList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// MoveDisk moves a persistent disk from one zone to another.
+func (c *projectsRESTClient) MoveDisk(ctx context.Context, req *computepb.MoveDiskProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDiskMoveRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/moveDisk", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// MoveInstance moves an instance and its attached persistent disks from one zone to another.
+func (c *projectsRESTClient) MoveInstance(ctx context.Context, req *computepb.MoveInstanceProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceMoveRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/moveInstance", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetCommonInstanceMetadata sets metadata common to all instances within the specified project using the data included in the request.
+func (c *projectsRESTClient) SetCommonInstanceMetadata(ctx context.Context, req *computepb.SetCommonInstanceMetadataProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetMetadataResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/setCommonInstanceMetadata", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetDefaultNetworkTier sets the default network tier of the project. The default network tier is used when an address/forwardingRule/instance is created without specifying the network tier field.
+func (c *projectsRESTClient) SetDefaultNetworkTier(ctx context.Context, req *computepb.SetDefaultNetworkTierProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetProjectsSetDefaultNetworkTierRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/setDefaultNetworkTier", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetUsageExportBucket enables the usage export feature and sets the usage export bucket where reports are stored. If you provide an empty request body using this method, the usage export feature will be disabled.
+func (c *projectsRESTClient) SetUsageExportBucket(ctx context.Context, req *computepb.SetUsageExportBucketProjectRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUsageExportLocationResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/setUsageExportBucket", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/projects_client_example_test.go b/compute/apiv1/projects_client_example_test.go
new file mode 100644
index 0000000..7ef81b6
--- /dev/null
+++ b/compute/apiv1/projects_client_example_test.go
@@ -0,0 +1,283 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewProjectsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleProjectsClient_DisableXpnHost() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DisableXpnHostProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DisableXpnHost(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_DisableXpnResource() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DisableXpnResourceProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DisableXpnResource(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_EnableXpnHost() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.EnableXpnHostProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.EnableXpnHost(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_EnableXpnResource() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.EnableXpnResourceProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.EnableXpnResource(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_GetXpnHost() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetXpnHostProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetXpnHost(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_GetXpnResources() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetXpnResourcesProjectsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetXpnResources(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_ListXpnHosts() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListXpnHostsProjectsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListXpnHosts(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_MoveDisk() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.MoveDiskProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.MoveDisk(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_MoveInstance() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.MoveInstanceProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.MoveInstance(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_SetCommonInstanceMetadata() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetCommonInstanceMetadataProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetCommonInstanceMetadata(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_SetDefaultNetworkTier() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetDefaultNetworkTierProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetDefaultNetworkTier(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleProjectsClient_SetUsageExportBucket() {
+	ctx := context.Background()
+	c, err := compute.NewProjectsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetUsageExportBucketProjectRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetUsageExportBucket(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/public_advertised_prefixes_client.go b/compute/apiv1/public_advertised_prefixes_client.go
new file mode 100644
index 0000000..01f9fa0
--- /dev/null
+++ b/compute/apiv1/public_advertised_prefixes_client.go
@@ -0,0 +1,438 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newPublicAdvertisedPrefixesClientHook clientHook
+
+// PublicAdvertisedPrefixesCallOptions contains the retry settings for each method of PublicAdvertisedPrefixesClient.
+type PublicAdvertisedPrefixesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+}
+
+// internalPublicAdvertisedPrefixesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalPublicAdvertisedPrefixesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeletePublicAdvertisedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetPublicAdvertisedPrefixeRequest, ...gax.CallOption) (*computepb.PublicAdvertisedPrefix, error)
+	Insert(context.Context, *computepb.InsertPublicAdvertisedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListPublicAdvertisedPrefixesRequest, ...gax.CallOption) (*computepb.PublicAdvertisedPrefixList, error)
+	Patch(context.Context, *computepb.PatchPublicAdvertisedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// PublicAdvertisedPrefixesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The PublicAdvertisedPrefixes API.
+type PublicAdvertisedPrefixesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalPublicAdvertisedPrefixesClient
+
+	// The call options for this service.
+	CallOptions *PublicAdvertisedPrefixesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *PublicAdvertisedPrefixesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *PublicAdvertisedPrefixesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *PublicAdvertisedPrefixesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified PublicAdvertisedPrefix
+func (c *PublicAdvertisedPrefixesClient) Delete(ctx context.Context, req *computepb.DeletePublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified PublicAdvertisedPrefix resource.
+func (c *PublicAdvertisedPrefixesClient) Get(ctx context.Context, req *computepb.GetPublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.PublicAdvertisedPrefix, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a PublicAdvertisedPrefix in the specified project using the parameters that are included in the request.
+func (c *PublicAdvertisedPrefixesClient) Insert(ctx context.Context, req *computepb.InsertPublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists the PublicAdvertisedPrefixes for a project.
+func (c *PublicAdvertisedPrefixesClient) List(ctx context.Context, req *computepb.ListPublicAdvertisedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicAdvertisedPrefixList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified Router resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *PublicAdvertisedPrefixesClient) Patch(ctx context.Context, req *computepb.PatchPublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type publicAdvertisedPrefixesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewPublicAdvertisedPrefixesRESTClient creates a new public advertised prefixes rest client.
+//
+// The PublicAdvertisedPrefixes API.
+func NewPublicAdvertisedPrefixesRESTClient(ctx context.Context, opts ...option.ClientOption) (*PublicAdvertisedPrefixesClient, error) {
+	clientOpts := append(defaultPublicAdvertisedPrefixesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &publicAdvertisedPrefixesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &PublicAdvertisedPrefixesClient{internalClient: c, CallOptions: &PublicAdvertisedPrefixesCallOptions{}}, nil
+}
+
+func defaultPublicAdvertisedPrefixesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *publicAdvertisedPrefixesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *publicAdvertisedPrefixesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *publicAdvertisedPrefixesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified PublicAdvertisedPrefix
+func (c *publicAdvertisedPrefixesRESTClient) Delete(ctx context.Context, req *computepb.DeletePublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicAdvertisedPrefixes/%v", req.GetProject(), req.GetPublicAdvertisedPrefix())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified PublicAdvertisedPrefix resource.
+func (c *publicAdvertisedPrefixesRESTClient) Get(ctx context.Context, req *computepb.GetPublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.PublicAdvertisedPrefix, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicAdvertisedPrefixes/%v", req.GetProject(), req.GetPublicAdvertisedPrefix())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicAdvertisedPrefix{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a PublicAdvertisedPrefix in the specified project using the parameters that are included in the request.
+func (c *publicAdvertisedPrefixesRESTClient) Insert(ctx context.Context, req *computepb.InsertPublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPublicAdvertisedPrefixResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicAdvertisedPrefixes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists the PublicAdvertisedPrefixes for a project.
+func (c *publicAdvertisedPrefixesRESTClient) List(ctx context.Context, req *computepb.ListPublicAdvertisedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicAdvertisedPrefixList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicAdvertisedPrefixes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicAdvertisedPrefixList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified Router resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *publicAdvertisedPrefixesRESTClient) Patch(ctx context.Context, req *computepb.PatchPublicAdvertisedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPublicAdvertisedPrefixResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/publicAdvertisedPrefixes/%v", req.GetProject(), req.GetPublicAdvertisedPrefix())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/public_advertised_prefixes_client_example_test.go b/compute/apiv1/public_advertised_prefixes_client_example_test.go
new file mode 100644
index 0000000..157318c
--- /dev/null
+++ b/compute/apiv1/public_advertised_prefixes_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewPublicAdvertisedPrefixesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewPublicAdvertisedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExamplePublicAdvertisedPrefixesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewPublicAdvertisedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeletePublicAdvertisedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicAdvertisedPrefixesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewPublicAdvertisedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetPublicAdvertisedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicAdvertisedPrefixesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewPublicAdvertisedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertPublicAdvertisedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicAdvertisedPrefixesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewPublicAdvertisedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPublicAdvertisedPrefixesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicAdvertisedPrefixesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewPublicAdvertisedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchPublicAdvertisedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/public_delegated_prefixes_client.go b/compute/apiv1/public_delegated_prefixes_client.go
new file mode 100644
index 0000000..5a186c8
--- /dev/null
+++ b/compute/apiv1/public_delegated_prefixes_client.go
@@ -0,0 +1,510 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newPublicDelegatedPrefixesClientHook clientHook
+
+// PublicDelegatedPrefixesCallOptions contains the retry settings for each method of PublicDelegatedPrefixesClient.
+type PublicDelegatedPrefixesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+}
+
+// internalPublicDelegatedPrefixesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalPublicDelegatedPrefixesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListPublicDelegatedPrefixesRequest, ...gax.CallOption) (*computepb.PublicDelegatedPrefixAggregatedList, error)
+	Delete(context.Context, *computepb.DeletePublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.PublicDelegatedPrefix, error)
+	Insert(context.Context, *computepb.InsertPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListPublicDelegatedPrefixesRequest, ...gax.CallOption) (*computepb.PublicDelegatedPrefixList, error)
+	Patch(context.Context, *computepb.PatchPublicDelegatedPrefixeRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// PublicDelegatedPrefixesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The PublicDelegatedPrefixes API.
+type PublicDelegatedPrefixesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalPublicDelegatedPrefixesClient
+
+	// The call options for this service.
+	CallOptions *PublicDelegatedPrefixesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *PublicDelegatedPrefixesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *PublicDelegatedPrefixesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *PublicDelegatedPrefixesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList lists all PublicDelegatedPrefix resources owned by the specific project across all scopes.
+func (c *PublicDelegatedPrefixesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListPublicDelegatedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefixAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified PublicDelegatedPrefix in the given region.
+func (c *PublicDelegatedPrefixesClient) Delete(ctx context.Context, req *computepb.DeletePublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified PublicDelegatedPrefix resource in the given region.
+func (c *PublicDelegatedPrefixesClient) Get(ctx context.Context, req *computepb.GetPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefix, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a PublicDelegatedPrefix in the specified project in the given region using the parameters that are included in the request.
+func (c *PublicDelegatedPrefixesClient) Insert(ctx context.Context, req *computepb.InsertPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists the PublicDelegatedPrefixes for a project in the given region.
+func (c *PublicDelegatedPrefixesClient) List(ctx context.Context, req *computepb.ListPublicDelegatedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefixList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified PublicDelegatedPrefix resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *PublicDelegatedPrefixesClient) Patch(ctx context.Context, req *computepb.PatchPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type publicDelegatedPrefixesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewPublicDelegatedPrefixesRESTClient creates a new public delegated prefixes rest client.
+//
+// The PublicDelegatedPrefixes API.
+func NewPublicDelegatedPrefixesRESTClient(ctx context.Context, opts ...option.ClientOption) (*PublicDelegatedPrefixesClient, error) {
+	clientOpts := append(defaultPublicDelegatedPrefixesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &publicDelegatedPrefixesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &PublicDelegatedPrefixesClient{internalClient: c, CallOptions: &PublicDelegatedPrefixesCallOptions{}}, nil
+}
+
+func defaultPublicDelegatedPrefixesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *publicDelegatedPrefixesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *publicDelegatedPrefixesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *publicDelegatedPrefixesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList lists all PublicDelegatedPrefix resources owned by the specific project across all scopes.
+func (c *publicDelegatedPrefixesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListPublicDelegatedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefixAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/publicDelegatedPrefixes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicDelegatedPrefixAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified PublicDelegatedPrefix in the given region.
+func (c *publicDelegatedPrefixesRESTClient) Delete(ctx context.Context, req *computepb.DeletePublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/publicDelegatedPrefixes/%v", req.GetProject(), req.GetRegion(), req.GetPublicDelegatedPrefix())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified PublicDelegatedPrefix resource in the given region.
+func (c *publicDelegatedPrefixesRESTClient) Get(ctx context.Context, req *computepb.GetPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefix, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/publicDelegatedPrefixes/%v", req.GetProject(), req.GetRegion(), req.GetPublicDelegatedPrefix())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicDelegatedPrefix{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a PublicDelegatedPrefix in the specified project in the given region using the parameters that are included in the request.
+func (c *publicDelegatedPrefixesRESTClient) Insert(ctx context.Context, req *computepb.InsertPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPublicDelegatedPrefixResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/publicDelegatedPrefixes", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists the PublicDelegatedPrefixes for a project in the given region.
+func (c *publicDelegatedPrefixesRESTClient) List(ctx context.Context, req *computepb.ListPublicDelegatedPrefixesRequest, opts ...gax.CallOption) (*computepb.PublicDelegatedPrefixList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/publicDelegatedPrefixes", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.PublicDelegatedPrefixList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified PublicDelegatedPrefix resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *publicDelegatedPrefixesRESTClient) Patch(ctx context.Context, req *computepb.PatchPublicDelegatedPrefixeRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetPublicDelegatedPrefixResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/publicDelegatedPrefixes/%v", req.GetProject(), req.GetRegion(), req.GetPublicDelegatedPrefix())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/public_delegated_prefixes_client_example_test.go b/compute/apiv1/public_delegated_prefixes_client_example_test.go
new file mode 100644
index 0000000..c17586c
--- /dev/null
+++ b/compute/apiv1/public_delegated_prefixes_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewPublicDelegatedPrefixesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExamplePublicDelegatedPrefixesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListPublicDelegatedPrefixesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicDelegatedPrefixesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeletePublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicDelegatedPrefixesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicDelegatedPrefixesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicDelegatedPrefixesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPublicDelegatedPrefixesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExamplePublicDelegatedPrefixesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewPublicDelegatedPrefixesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchPublicDelegatedPrefixeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_autoscalers_client.go b/compute/apiv1/region_autoscalers_client.go
new file mode 100644
index 0000000..32c026f
--- /dev/null
+++ b/compute/apiv1/region_autoscalers_client.go
@@ -0,0 +1,508 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionAutoscalersClientHook clientHook
+
+// RegionAutoscalersCallOptions contains the retry settings for each method of RegionAutoscalersClient.
+type RegionAutoscalersCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+	Update []gax.CallOption
+}
+
+// internalRegionAutoscalersClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionAutoscalersClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionAutoscalerRequest, ...gax.CallOption) (*computepb.Autoscaler, error)
+	Insert(context.Context, *computepb.InsertRegionAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionAutoscalersRequest, ...gax.CallOption) (*computepb.RegionAutoscalerList, error)
+	Patch(context.Context, *computepb.PatchRegionAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateRegionAutoscalerRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionAutoscalersClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionAutoscalers API.
+type RegionAutoscalersClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionAutoscalersClient
+
+	// The call options for this service.
+	CallOptions *RegionAutoscalersCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionAutoscalersClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionAutoscalersClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionAutoscalersClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified autoscaler.
+func (c *RegionAutoscalersClient) Delete(ctx context.Context, req *computepb.DeleteRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified autoscaler.
+func (c *RegionAutoscalersClient) Get(ctx context.Context, req *computepb.GetRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Autoscaler, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates an autoscaler in the specified project using the data included in the request.
+func (c *RegionAutoscalersClient) Insert(ctx context.Context, req *computepb.InsertRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of autoscalers contained within the specified region.
+func (c *RegionAutoscalersClient) List(ctx context.Context, req *computepb.ListRegionAutoscalersRequest, opts ...gax.CallOption) (*computepb.RegionAutoscalerList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates an autoscaler in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *RegionAutoscalersClient) Patch(ctx context.Context, req *computepb.PatchRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates an autoscaler in the specified project using the data included in the request.
+func (c *RegionAutoscalersClient) Update(ctx context.Context, req *computepb.UpdateRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionAutoscalersRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionAutoscalersRESTClient creates a new region autoscalers rest client.
+//
+// The RegionAutoscalers API.
+func NewRegionAutoscalersRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionAutoscalersClient, error) {
+	clientOpts := append(defaultRegionAutoscalersRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionAutoscalersRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionAutoscalersClient{internalClient: c, CallOptions: &RegionAutoscalersCallOptions{}}, nil
+}
+
+func defaultRegionAutoscalersRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionAutoscalersRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionAutoscalersRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionAutoscalersRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified autoscaler.
+func (c *regionAutoscalersRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/autoscalers/%v", req.GetProject(), req.GetRegion(), req.GetAutoscaler())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified autoscaler.
+func (c *regionAutoscalersRESTClient) Get(ctx context.Context, req *computepb.GetRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Autoscaler, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/autoscalers/%v", req.GetProject(), req.GetRegion(), req.GetAutoscaler())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Autoscaler{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates an autoscaler in the specified project using the data included in the request.
+func (c *regionAutoscalersRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAutoscalerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/autoscalers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of autoscalers contained within the specified region.
+func (c *regionAutoscalersRESTClient) List(ctx context.Context, req *computepb.ListRegionAutoscalersRequest, opts ...gax.CallOption) (*computepb.RegionAutoscalerList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/autoscalers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionAutoscalerList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates an autoscaler in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *regionAutoscalersRESTClient) Patch(ctx context.Context, req *computepb.PatchRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAutoscalerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/autoscalers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Autoscaler != nil {
+		params.Add("autoscaler", fmt.Sprintf("%v", req.GetAutoscaler()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates an autoscaler in the specified project using the data included in the request.
+func (c *regionAutoscalersRESTClient) Update(ctx context.Context, req *computepb.UpdateRegionAutoscalerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetAutoscalerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req != nil && req.Autoscaler != nil {
+		params.Add("autoscaler", fmt.Sprintf("%v", req.GetAutoscaler()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req.GetRegion() != "" {
+		params.Add("region", fmt.Sprintf("%v", req.GetRegion()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_autoscalers_client_example_test.go b/compute/apiv1/region_autoscalers_client_example_test.go
new file mode 100644
index 0000000..b3cf733
--- /dev/null
+++ b/compute/apiv1/region_autoscalers_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionAutoscalersRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionAutoscalersClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionAutoscalersClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionAutoscalersClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionAutoscalersClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionAutoscalersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionAutoscalersClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRegionAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionAutoscalersClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewRegionAutoscalersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateRegionAutoscalerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_backend_services_client.go b/compute/apiv1/region_backend_services_client.go
new file mode 100644
index 0000000..eae9580
--- /dev/null
+++ b/compute/apiv1/region_backend_services_client.go
@@ -0,0 +1,556 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionBackendServicesClientHook clientHook
+
+// RegionBackendServicesCallOptions contains the retry settings for each method of RegionBackendServicesClient.
+type RegionBackendServicesCallOptions struct {
+	Delete    []gax.CallOption
+	Get       []gax.CallOption
+	GetHealth []gax.CallOption
+	Insert    []gax.CallOption
+	List      []gax.CallOption
+	Patch     []gax.CallOption
+	Update    []gax.CallOption
+}
+
+// internalRegionBackendServicesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionBackendServicesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionBackendServiceRequest, ...gax.CallOption) (*computepb.BackendService, error)
+	GetHealth(context.Context, *computepb.GetHealthRegionBackendServiceRequest, ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error)
+	Insert(context.Context, *computepb.InsertRegionBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionBackendServicesRequest, ...gax.CallOption) (*computepb.BackendServiceList, error)
+	Patch(context.Context, *computepb.PatchRegionBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateRegionBackendServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionBackendServicesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionBackendServices API.
+type RegionBackendServicesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionBackendServicesClient
+
+	// The call options for this service.
+	CallOptions *RegionBackendServicesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionBackendServicesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionBackendServicesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionBackendServicesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified regional BackendService resource.
+func (c *RegionBackendServicesClient) Delete(ctx context.Context, req *computepb.DeleteRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified regional BackendService resource.
+func (c *RegionBackendServicesClient) Get(ctx context.Context, req *computepb.GetRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendService, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetHealth gets the most recent health check results for this regional BackendService.
+func (c *RegionBackendServicesClient) GetHealth(ctx context.Context, req *computepb.GetHealthRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error) {
+	return c.internalClient.GetHealth(ctx, req, opts...)
+}
+
+// Insert creates a regional BackendService resource in the specified project using the data included in the request. For more information, see  Backend services overview.
+func (c *RegionBackendServicesClient) Insert(ctx context.Context, req *computepb.InsertRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of regional BackendService resources available to the specified project in the given region.
+func (c *RegionBackendServicesClient) List(ctx context.Context, req *computepb.ListRegionBackendServicesRequest, opts ...gax.CallOption) (*computepb.BackendServiceList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified regional BackendService resource with the data included in the request. For more information, see  Understanding backend services This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *RegionBackendServicesClient) Patch(ctx context.Context, req *computepb.PatchRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates the specified regional BackendService resource with the data included in the request. For more information, see  Backend services overview.
+func (c *RegionBackendServicesClient) Update(ctx context.Context, req *computepb.UpdateRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionBackendServicesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionBackendServicesRESTClient creates a new region backend services rest client.
+//
+// The RegionBackendServices API.
+func NewRegionBackendServicesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionBackendServicesClient, error) {
+	clientOpts := append(defaultRegionBackendServicesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionBackendServicesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionBackendServicesClient{internalClient: c, CallOptions: &RegionBackendServicesCallOptions{}}, nil
+}
+
+func defaultRegionBackendServicesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionBackendServicesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionBackendServicesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionBackendServicesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified regional BackendService resource.
+func (c *regionBackendServicesRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/backendServices/%v", req.GetProject(), req.GetRegion(), req.GetBackendService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified regional BackendService resource.
+func (c *regionBackendServicesRESTClient) Get(ctx context.Context, req *computepb.GetRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendService, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/backendServices/%v", req.GetProject(), req.GetRegion(), req.GetBackendService())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendService{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetHealth gets the most recent health check results for this regional BackendService.
+func (c *regionBackendServicesRESTClient) GetHealth(ctx context.Context, req *computepb.GetHealthRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.BackendServiceGroupHealth, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetResourceGroupReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/backendServices/%v/getHealth", req.GetProject(), req.GetRegion(), req.GetBackendService())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendServiceGroupHealth{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a regional BackendService resource in the specified project using the data included in the request. For more information, see  Backend services overview.
+func (c *regionBackendServicesRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/backendServices", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of regional BackendService resources available to the specified project in the given region.
+func (c *regionBackendServicesRESTClient) List(ctx context.Context, req *computepb.ListRegionBackendServicesRequest, opts ...gax.CallOption) (*computepb.BackendServiceList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/backendServices", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.BackendServiceList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified regional BackendService resource with the data included in the request. For more information, see  Understanding backend services This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *regionBackendServicesRESTClient) Patch(ctx context.Context, req *computepb.PatchRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/backendServices/%v", req.GetProject(), req.GetRegion(), req.GetBackendService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified regional BackendService resource with the data included in the request. For more information, see  Backend services overview.
+func (c *regionBackendServicesRESTClient) Update(ctx context.Context, req *computepb.UpdateRegionBackendServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBackendServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetBackendService() != "" {
+		params.Add("backendService", fmt.Sprintf("%v", req.GetBackendService()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req.GetRegion() != "" {
+		params.Add("region", fmt.Sprintf("%v", req.GetRegion()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_backend_services_client_example_test.go b/compute/apiv1/region_backend_services_client_example_test.go
new file mode 100644
index 0000000..389fa32
--- /dev/null
+++ b/compute/apiv1/region_backend_services_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionBackendServicesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionBackendServicesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionBackendServicesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionBackendServicesClient_GetHealth() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetHealthRegionBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetHealth(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionBackendServicesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionBackendServicesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionBackendServicesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionBackendServicesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRegionBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionBackendServicesClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewRegionBackendServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateRegionBackendServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_commitments_client.go b/compute/apiv1/region_commitments_client.go
new file mode 100644
index 0000000..c099069
--- /dev/null
+++ b/compute/apiv1/region_commitments_client.go
@@ -0,0 +1,395 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionCommitmentsClientHook clientHook
+
+// RegionCommitmentsCallOptions contains the retry settings for each method of RegionCommitmentsClient.
+type RegionCommitmentsCallOptions struct {
+	AggregatedList []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalRegionCommitmentsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionCommitmentsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListRegionCommitmentsRequest, ...gax.CallOption) (*computepb.CommitmentAggregatedList, error)
+	Get(context.Context, *computepb.GetRegionCommitmentRequest, ...gax.CallOption) (*computepb.Commitment, error)
+	Insert(context.Context, *computepb.InsertRegionCommitmentRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionCommitmentsRequest, ...gax.CallOption) (*computepb.CommitmentList, error)
+}
+
+// RegionCommitmentsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionCommitments API.
+type RegionCommitmentsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionCommitmentsClient
+
+	// The call options for this service.
+	CallOptions *RegionCommitmentsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionCommitmentsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionCommitmentsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionCommitmentsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of commitments.
+func (c *RegionCommitmentsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListRegionCommitmentsRequest, opts ...gax.CallOption) (*computepb.CommitmentAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Get returns the specified commitment resource. Gets a list of available commitments by making a list() request.
+func (c *RegionCommitmentsClient) Get(ctx context.Context, req *computepb.GetRegionCommitmentRequest, opts ...gax.CallOption) (*computepb.Commitment, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a commitment in the specified project using the data included in the request.
+func (c *RegionCommitmentsClient) Insert(ctx context.Context, req *computepb.InsertRegionCommitmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of commitments contained within the specified region.
+func (c *RegionCommitmentsClient) List(ctx context.Context, req *computepb.ListRegionCommitmentsRequest, opts ...gax.CallOption) (*computepb.CommitmentList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionCommitmentsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionCommitmentsRESTClient creates a new region commitments rest client.
+//
+// The RegionCommitments API.
+func NewRegionCommitmentsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionCommitmentsClient, error) {
+	clientOpts := append(defaultRegionCommitmentsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionCommitmentsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionCommitmentsClient{internalClient: c, CallOptions: &RegionCommitmentsCallOptions{}}, nil
+}
+
+func defaultRegionCommitmentsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionCommitmentsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionCommitmentsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionCommitmentsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of commitments.
+func (c *regionCommitmentsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListRegionCommitmentsRequest, opts ...gax.CallOption) (*computepb.CommitmentAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/commitments", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.CommitmentAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified commitment resource. Gets a list of available commitments by making a list() request.
+func (c *regionCommitmentsRESTClient) Get(ctx context.Context, req *computepb.GetRegionCommitmentRequest, opts ...gax.CallOption) (*computepb.Commitment, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/commitments/%v", req.GetProject(), req.GetRegion(), req.GetCommitment())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Commitment{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a commitment in the specified project using the data included in the request.
+func (c *regionCommitmentsRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionCommitmentRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetCommitmentResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/commitments", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of commitments contained within the specified region.
+func (c *regionCommitmentsRESTClient) List(ctx context.Context, req *computepb.ListRegionCommitmentsRequest, opts ...gax.CallOption) (*computepb.CommitmentList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/commitments", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.CommitmentList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_commitments_client_example_test.go b/compute/apiv1/region_commitments_client_example_test.go
new file mode 100644
index 0000000..5cc6856
--- /dev/null
+++ b/compute/apiv1/region_commitments_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionCommitmentsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionCommitmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionCommitmentsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewRegionCommitmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListRegionCommitmentsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionCommitmentsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionCommitmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionCommitmentRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionCommitmentsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionCommitmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionCommitmentRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionCommitmentsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionCommitmentsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionCommitmentsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_disk_types_client.go b/compute/apiv1/region_disk_types_client.go
new file mode 100644
index 0000000..cc443bb
--- /dev/null
+++ b/compute/apiv1/region_disk_types_client.go
@@ -0,0 +1,265 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionDiskTypesClientHook clientHook
+
+// RegionDiskTypesCallOptions contains the retry settings for each method of RegionDiskTypesClient.
+type RegionDiskTypesCallOptions struct {
+	Get  []gax.CallOption
+	List []gax.CallOption
+}
+
+// internalRegionDiskTypesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionDiskTypesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Get(context.Context, *computepb.GetRegionDiskTypeRequest, ...gax.CallOption) (*computepb.DiskType, error)
+	List(context.Context, *computepb.ListRegionDiskTypesRequest, ...gax.CallOption) (*computepb.RegionDiskTypeList, error)
+}
+
+// RegionDiskTypesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionDiskTypes API.
+type RegionDiskTypesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionDiskTypesClient
+
+	// The call options for this service.
+	CallOptions *RegionDiskTypesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionDiskTypesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionDiskTypesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionDiskTypesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Get returns the specified regional disk type. Gets a list of available disk types by making a list() request.
+func (c *RegionDiskTypesClient) Get(ctx context.Context, req *computepb.GetRegionDiskTypeRequest, opts ...gax.CallOption) (*computepb.DiskType, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of regional disk types available to the specified project.
+func (c *RegionDiskTypesClient) List(ctx context.Context, req *computepb.ListRegionDiskTypesRequest, opts ...gax.CallOption) (*computepb.RegionDiskTypeList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionDiskTypesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionDiskTypesRESTClient creates a new region disk types rest client.
+//
+// The RegionDiskTypes API.
+func NewRegionDiskTypesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionDiskTypesClient, error) {
+	clientOpts := append(defaultRegionDiskTypesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionDiskTypesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionDiskTypesClient{internalClient: c, CallOptions: &RegionDiskTypesCallOptions{}}, nil
+}
+
+func defaultRegionDiskTypesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionDiskTypesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionDiskTypesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionDiskTypesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Get returns the specified regional disk type. Gets a list of available disk types by making a list() request.
+func (c *regionDiskTypesRESTClient) Get(ctx context.Context, req *computepb.GetRegionDiskTypeRequest, opts ...gax.CallOption) (*computepb.DiskType, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/diskTypes/%v", req.GetProject(), req.GetRegion(), req.GetDiskType())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskType{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of regional disk types available to the specified project.
+func (c *regionDiskTypesRESTClient) List(ctx context.Context, req *computepb.ListRegionDiskTypesRequest, opts ...gax.CallOption) (*computepb.RegionDiskTypeList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/diskTypes", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionDiskTypeList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_disk_types_client_example_test.go b/compute/apiv1/region_disk_types_client_example_test.go
new file mode 100644
index 0000000..a7d3445
--- /dev/null
+++ b/compute/apiv1/region_disk_types_client_example_test.go
@@ -0,0 +1,74 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionDiskTypesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionDiskTypesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionDiskTypeRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDiskTypesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDiskTypesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionDiskTypesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_disks_client.go b/compute/apiv1/region_disks_client.go
new file mode 100644
index 0000000..5707403
--- /dev/null
+++ b/compute/apiv1/region_disks_client.go
@@ -0,0 +1,832 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionDisksClientHook clientHook
+
+// RegionDisksCallOptions contains the retry settings for each method of RegionDisksClient.
+type RegionDisksCallOptions struct {
+	AddResourcePolicies    []gax.CallOption
+	CreateSnapshot         []gax.CallOption
+	Delete                 []gax.CallOption
+	Get                    []gax.CallOption
+	GetIamPolicy           []gax.CallOption
+	Insert                 []gax.CallOption
+	List                   []gax.CallOption
+	RemoveResourcePolicies []gax.CallOption
+	Resize                 []gax.CallOption
+	SetIamPolicy           []gax.CallOption
+	SetLabels              []gax.CallOption
+	TestIamPermissions     []gax.CallOption
+}
+
+// internalRegionDisksClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionDisksClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddResourcePolicies(context.Context, *computepb.AddResourcePoliciesRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	CreateSnapshot(context.Context, *computepb.CreateSnapshotRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionDiskRequest, ...gax.CallOption) (*computepb.Disk, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyRegionDiskRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionDisksRequest, ...gax.CallOption) (*computepb.DiskList, error)
+	RemoveResourcePolicies(context.Context, *computepb.RemoveResourcePoliciesRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Resize(context.Context, *computepb.ResizeRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyRegionDiskRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetLabels(context.Context, *computepb.SetLabelsRegionDiskRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsRegionDiskRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// RegionDisksClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionDisks API.
+type RegionDisksClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionDisksClient
+
+	// The call options for this service.
+	CallOptions *RegionDisksCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionDisksClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionDisksClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionDisksClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddResourcePolicies adds existing resource policies to a regional disk. You can only add one policy which will be applied to this disk for scheduling snapshot creation.
+func (c *RegionDisksClient) AddResourcePolicies(ctx context.Context, req *computepb.AddResourcePoliciesRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddResourcePolicies(ctx, req, opts...)
+}
+
+// CreateSnapshot creates a snapshot of this regional disk.
+func (c *RegionDisksClient) CreateSnapshot(ctx context.Context, req *computepb.CreateSnapshotRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.CreateSnapshot(ctx, req, opts...)
+}
+
+// Delete deletes the specified regional persistent disk. Deleting a regional disk removes all the replicas of its data permanently and is irreversible. However, deleting a disk does not delete any snapshots previously made from the disk. You must separately delete snapshots.
+func (c *RegionDisksClient) Delete(ctx context.Context, req *computepb.DeleteRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns a specified regional persistent disk.
+func (c *RegionDisksClient) Get(ctx context.Context, req *computepb.GetRegionDiskRequest, opts ...gax.CallOption) (*computepb.Disk, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *RegionDisksClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyRegionDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a persistent regional disk in the specified project using the data included in the request.
+func (c *RegionDisksClient) Insert(ctx context.Context, req *computepb.InsertRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of persistent disks contained within the specified region.
+func (c *RegionDisksClient) List(ctx context.Context, req *computepb.ListRegionDisksRequest, opts ...gax.CallOption) (*computepb.DiskList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// RemoveResourcePolicies removes resource policies from a regional disk.
+func (c *RegionDisksClient) RemoveResourcePolicies(ctx context.Context, req *computepb.RemoveResourcePoliciesRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveResourcePolicies(ctx, req, opts...)
+}
+
+// Resize resizes the specified regional persistent disk.
+func (c *RegionDisksClient) Resize(ctx context.Context, req *computepb.ResizeRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Resize(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *RegionDisksClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyRegionDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on the target regional disk.
+func (c *RegionDisksClient) SetLabels(ctx context.Context, req *computepb.SetLabelsRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *RegionDisksClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsRegionDiskRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionDisksRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionDisksRESTClient creates a new region disks rest client.
+//
+// The RegionDisks API.
+func NewRegionDisksRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionDisksClient, error) {
+	clientOpts := append(defaultRegionDisksRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionDisksRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionDisksClient{internalClient: c, CallOptions: &RegionDisksCallOptions{}}, nil
+}
+
+func defaultRegionDisksRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionDisksRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionDisksRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionDisksRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddResourcePolicies adds existing resource policies to a regional disk. You can only add one policy which will be applied to this disk for scheduling snapshot creation.
+func (c *regionDisksRESTClient) AddResourcePolicies(ctx context.Context, req *computepb.AddResourcePoliciesRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionDisksAddResourcePoliciesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/addResourcePolicies", req.GetProject(), req.GetRegion(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// CreateSnapshot creates a snapshot of this regional disk.
+func (c *regionDisksRESTClient) CreateSnapshot(ctx context.Context, req *computepb.CreateSnapshotRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSnapshotResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/createSnapshot", req.GetProject(), req.GetRegion(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified regional persistent disk. Deleting a regional disk removes all the replicas of its data permanently and is irreversible. However, deleting a disk does not delete any snapshots previously made from the disk. You must separately delete snapshots.
+func (c *regionDisksRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v", req.GetProject(), req.GetRegion(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns a specified regional persistent disk.
+func (c *regionDisksRESTClient) Get(ctx context.Context, req *computepb.GetRegionDiskRequest, opts ...gax.CallOption) (*computepb.Disk, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v", req.GetProject(), req.GetRegion(), req.GetDisk())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Disk{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *regionDisksRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyRegionDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/getIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a persistent regional disk in the specified project using the data included in the request.
+func (c *regionDisksRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetDiskResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req != nil && req.SourceImage != nil {
+		params.Add("sourceImage", fmt.Sprintf("%v", req.GetSourceImage()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of persistent disks contained within the specified region.
+func (c *regionDisksRESTClient) List(ctx context.Context, req *computepb.ListRegionDisksRequest, opts ...gax.CallOption) (*computepb.DiskList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DiskList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveResourcePolicies removes resource policies from a regional disk.
+func (c *regionDisksRESTClient) RemoveResourcePolicies(ctx context.Context, req *computepb.RemoveResourcePoliciesRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionDisksRemoveResourcePoliciesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/removeResourcePolicies", req.GetProject(), req.GetRegion(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Resize resizes the specified regional persistent disk.
+func (c *regionDisksRESTClient) Resize(ctx context.Context, req *computepb.ResizeRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionDisksResizeRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/resize", req.GetProject(), req.GetRegion(), req.GetDisk())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *regionDisksRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyRegionDiskRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/setIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on the target regional disk.
+func (c *regionDisksRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsRegionDiskRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/setLabels", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *regionDisksRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsRegionDiskRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/disks/%v/testIamPermissions", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_disks_client_example_test.go b/compute/apiv1/region_disks_client_example_test.go
new file mode 100644
index 0000000..fbef394
--- /dev/null
+++ b/compute/apiv1/region_disks_client_example_test.go
@@ -0,0 +1,264 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionDisksRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionDisksClient_AddResourcePolicies() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddResourcePoliciesRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddResourcePolicies(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_CreateSnapshot() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.CreateSnapshotRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.CreateSnapshot(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionDisksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_RemoveResourcePolicies() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveResourcePoliciesRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveResourcePolicies(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_Resize() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ResizeRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Resize(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionDisksClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewRegionDisksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsRegionDiskRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_health_check_services_client.go b/compute/apiv1/region_health_check_services_client.go
new file mode 100644
index 0000000..7e7ece7
--- /dev/null
+++ b/compute/apiv1/region_health_check_services_client.go
@@ -0,0 +1,438 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionHealthCheckServicesClientHook clientHook
+
+// RegionHealthCheckServicesCallOptions contains the retry settings for each method of RegionHealthCheckServicesClient.
+type RegionHealthCheckServicesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+}
+
+// internalRegionHealthCheckServicesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionHealthCheckServicesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionHealthCheckServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionHealthCheckServiceRequest, ...gax.CallOption) (*computepb.HealthCheckService, error)
+	Insert(context.Context, *computepb.InsertRegionHealthCheckServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionHealthCheckServicesRequest, ...gax.CallOption) (*computepb.HealthCheckServicesList, error)
+	Patch(context.Context, *computepb.PatchRegionHealthCheckServiceRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionHealthCheckServicesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionHealthCheckServices API.
+type RegionHealthCheckServicesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionHealthCheckServicesClient
+
+	// The call options for this service.
+	CallOptions *RegionHealthCheckServicesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionHealthCheckServicesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionHealthCheckServicesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionHealthCheckServicesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified regional HealthCheckService.
+func (c *RegionHealthCheckServicesClient) Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified regional HealthCheckService resource.
+func (c *RegionHealthCheckServicesClient) Get(ctx context.Context, req *computepb.GetRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.HealthCheckService, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a regional HealthCheckService resource in the specified project and region using the data included in the request.
+func (c *RegionHealthCheckServicesClient) Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists all the HealthCheckService resources that have been configured for the specified project in the given region.
+func (c *RegionHealthCheckServicesClient) List(ctx context.Context, req *computepb.ListRegionHealthCheckServicesRequest, opts ...gax.CallOption) (*computepb.HealthCheckServicesList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates the specified regional HealthCheckService resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *RegionHealthCheckServicesClient) Patch(ctx context.Context, req *computepb.PatchRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionHealthCheckServicesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionHealthCheckServicesRESTClient creates a new region health check services rest client.
+//
+// The RegionHealthCheckServices API.
+func NewRegionHealthCheckServicesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionHealthCheckServicesClient, error) {
+	clientOpts := append(defaultRegionHealthCheckServicesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionHealthCheckServicesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionHealthCheckServicesClient{internalClient: c, CallOptions: &RegionHealthCheckServicesCallOptions{}}, nil
+}
+
+func defaultRegionHealthCheckServicesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionHealthCheckServicesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionHealthCheckServicesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionHealthCheckServicesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified regional HealthCheckService.
+func (c *regionHealthCheckServicesRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthCheckServices/%v", req.GetProject(), req.GetRegion(), req.GetHealthCheckService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified regional HealthCheckService resource.
+func (c *regionHealthCheckServicesRESTClient) Get(ctx context.Context, req *computepb.GetRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.HealthCheckService, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthCheckServices/%v", req.GetProject(), req.GetRegion(), req.GetHealthCheckService())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthCheckService{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a regional HealthCheckService resource in the specified project and region using the data included in the request.
+func (c *regionHealthCheckServicesRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthCheckServices", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists all the HealthCheckService resources that have been configured for the specified project in the given region.
+func (c *regionHealthCheckServicesRESTClient) List(ctx context.Context, req *computepb.ListRegionHealthCheckServicesRequest, opts ...gax.CallOption) (*computepb.HealthCheckServicesList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthCheckServices", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthCheckServicesList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates the specified regional HealthCheckService resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *regionHealthCheckServicesRESTClient) Patch(ctx context.Context, req *computepb.PatchRegionHealthCheckServiceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckServiceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthCheckServices/%v", req.GetProject(), req.GetRegion(), req.GetHealthCheckService())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_health_check_services_client_example_test.go b/compute/apiv1/region_health_check_services_client_example_test.go
new file mode 100644
index 0000000..bbaf17d
--- /dev/null
+++ b/compute/apiv1/region_health_check_services_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionHealthCheckServicesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthCheckServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionHealthCheckServicesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthCheckServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionHealthCheckServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthCheckServicesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthCheckServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionHealthCheckServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthCheckServicesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthCheckServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionHealthCheckServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthCheckServicesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthCheckServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionHealthCheckServicesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthCheckServicesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthCheckServicesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRegionHealthCheckServiceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_health_checks_client.go b/compute/apiv1/region_health_checks_client.go
new file mode 100644
index 0000000..18afaa3
--- /dev/null
+++ b/compute/apiv1/region_health_checks_client.go
@@ -0,0 +1,505 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionHealthChecksClientHook clientHook
+
+// RegionHealthChecksCallOptions contains the retry settings for each method of RegionHealthChecksClient.
+type RegionHealthChecksCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+	Update []gax.CallOption
+}
+
+// internalRegionHealthChecksClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionHealthChecksClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionHealthCheckRequest, ...gax.CallOption) (*computepb.HealthCheck, error)
+	Insert(context.Context, *computepb.InsertRegionHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionHealthChecksRequest, ...gax.CallOption) (*computepb.HealthCheckList, error)
+	Patch(context.Context, *computepb.PatchRegionHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateRegionHealthCheckRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionHealthChecksClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionHealthChecks API.
+type RegionHealthChecksClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionHealthChecksClient
+
+	// The call options for this service.
+	CallOptions *RegionHealthChecksCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionHealthChecksClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionHealthChecksClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionHealthChecksClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified HealthCheck resource.
+func (c *RegionHealthChecksClient) Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified HealthCheck resource. Gets a list of available health checks by making a list() request.
+func (c *RegionHealthChecksClient) Get(ctx context.Context, req *computepb.GetRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.HealthCheck, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a HealthCheck resource in the specified project using the data included in the request.
+func (c *RegionHealthChecksClient) Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of HealthCheck resources available to the specified project.
+func (c *RegionHealthChecksClient) List(ctx context.Context, req *computepb.ListRegionHealthChecksRequest, opts ...gax.CallOption) (*computepb.HealthCheckList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch updates a HealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *RegionHealthChecksClient) Patch(ctx context.Context, req *computepb.PatchRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates a HealthCheck resource in the specified project using the data included in the request.
+func (c *RegionHealthChecksClient) Update(ctx context.Context, req *computepb.UpdateRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionHealthChecksRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionHealthChecksRESTClient creates a new region health checks rest client.
+//
+// The RegionHealthChecks API.
+func NewRegionHealthChecksRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionHealthChecksClient, error) {
+	clientOpts := append(defaultRegionHealthChecksRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionHealthChecksRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionHealthChecksClient{internalClient: c, CallOptions: &RegionHealthChecksCallOptions{}}, nil
+}
+
+func defaultRegionHealthChecksRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionHealthChecksRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionHealthChecksRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionHealthChecksRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified HealthCheck resource.
+func (c *regionHealthChecksRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthChecks/%v", req.GetProject(), req.GetRegion(), req.GetHealthCheck())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified HealthCheck resource. Gets a list of available health checks by making a list() request.
+func (c *regionHealthChecksRESTClient) Get(ctx context.Context, req *computepb.GetRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.HealthCheck, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthChecks/%v", req.GetProject(), req.GetRegion(), req.GetHealthCheck())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthCheck{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a HealthCheck resource in the specified project using the data included in the request.
+func (c *regionHealthChecksRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthChecks", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of HealthCheck resources available to the specified project.
+func (c *regionHealthChecksRESTClient) List(ctx context.Context, req *computepb.ListRegionHealthChecksRequest, opts ...gax.CallOption) (*computepb.HealthCheckList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthChecks", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.HealthCheckList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates a HealthCheck resource in the specified project using the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *regionHealthChecksRESTClient) Patch(ctx context.Context, req *computepb.PatchRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/healthChecks/%v", req.GetProject(), req.GetRegion(), req.GetHealthCheck())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates a HealthCheck resource in the specified project using the data included in the request.
+func (c *regionHealthChecksRESTClient) Update(ctx context.Context, req *computepb.UpdateRegionHealthCheckRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetHealthCheckResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetHealthCheck() != "" {
+		params.Add("healthCheck", fmt.Sprintf("%v", req.GetHealthCheck()))
+	}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req.GetRegion() != "" {
+		params.Add("region", fmt.Sprintf("%v", req.GetRegion()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_health_checks_client_example_test.go b/compute/apiv1/region_health_checks_client_example_test.go
new file mode 100644
index 0000000..2264ab8
--- /dev/null
+++ b/compute/apiv1/region_health_checks_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionHealthChecksRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionHealthChecksClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthChecksClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthChecksClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthChecksClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionHealthChecksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthChecksClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRegionHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionHealthChecksClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewRegionHealthChecksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateRegionHealthCheckRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_instance_group_managers_client.go b/compute/apiv1/region_instance_group_managers_client.go
new file mode 100644
index 0000000..4e108c4
--- /dev/null
+++ b/compute/apiv1/region_instance_group_managers_client.go
@@ -0,0 +1,1307 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionInstanceGroupManagersClientHook clientHook
+
+// RegionInstanceGroupManagersCallOptions contains the retry settings for each method of RegionInstanceGroupManagersClient.
+type RegionInstanceGroupManagersCallOptions struct {
+	AbandonInstances         []gax.CallOption
+	ApplyUpdatesToInstances  []gax.CallOption
+	CreateInstances          []gax.CallOption
+	Delete                   []gax.CallOption
+	DeleteInstances          []gax.CallOption
+	DeletePerInstanceConfigs []gax.CallOption
+	Get                      []gax.CallOption
+	Insert                   []gax.CallOption
+	List                     []gax.CallOption
+	ListErrors               []gax.CallOption
+	ListManagedInstances     []gax.CallOption
+	ListPerInstanceConfigs   []gax.CallOption
+	Patch                    []gax.CallOption
+	PatchPerInstanceConfigs  []gax.CallOption
+	RecreateInstances        []gax.CallOption
+	Resize                   []gax.CallOption
+	SetInstanceTemplate      []gax.CallOption
+	SetTargetPools           []gax.CallOption
+	UpdatePerInstanceConfigs []gax.CallOption
+}
+
+// internalRegionInstanceGroupManagersClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionInstanceGroupManagersClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AbandonInstances(context.Context, *computepb.AbandonInstancesRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	ApplyUpdatesToInstances(context.Context, *computepb.ApplyUpdatesToInstancesRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	CreateInstances(context.Context, *computepb.CreateInstancesRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeleteInstances(context.Context, *computepb.DeleteInstancesRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	DeletePerInstanceConfigs(context.Context, *computepb.DeletePerInstanceConfigsRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.InstanceGroupManager, error)
+	Insert(context.Context, *computepb.InsertRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.RegionInstanceGroupManagerList, error)
+	ListErrors(context.Context, *computepb.ListErrorsRegionInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListErrorsResponse, error)
+	ListManagedInstances(context.Context, *computepb.ListManagedInstancesRegionInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListInstancesResponse, error)
+	ListPerInstanceConfigs(context.Context, *computepb.ListPerInstanceConfigsRegionInstanceGroupManagersRequest, ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListInstanceConfigsResp, error)
+	Patch(context.Context, *computepb.PatchRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	PatchPerInstanceConfigs(context.Context, *computepb.PatchPerInstanceConfigsRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RecreateInstances(context.Context, *computepb.RecreateInstancesRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Resize(context.Context, *computepb.ResizeRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetInstanceTemplate(context.Context, *computepb.SetInstanceTemplateRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetTargetPools(context.Context, *computepb.SetTargetPoolsRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+	UpdatePerInstanceConfigs(context.Context, *computepb.UpdatePerInstanceConfigsRegionInstanceGroupManagerRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionInstanceGroupManagersClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionInstanceGroupManagers API.
+type RegionInstanceGroupManagersClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionInstanceGroupManagersClient
+
+	// The call options for this service.
+	CallOptions *RegionInstanceGroupManagersCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionInstanceGroupManagersClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionInstanceGroupManagersClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionInstanceGroupManagersClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AbandonInstances flags the specified instances to be immediately removed from the managed instance group. Abandoning an instance does not delete the instance, but it does remove the instance from any target pools that are applied by the managed instance group. This method reduces the targetSize of the managed instance group by the number of instances that you abandon. This operation is marked as DONE when the action is scheduled even if the instances have not yet been removed from the group. You must separately verify the status of the abandoning action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *RegionInstanceGroupManagersClient) AbandonInstances(ctx context.Context, req *computepb.AbandonInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AbandonInstances(ctx, req, opts...)
+}
+
+// ApplyUpdatesToInstances apply updates to selected instances the managed instance group.
+func (c *RegionInstanceGroupManagersClient) ApplyUpdatesToInstances(ctx context.Context, req *computepb.ApplyUpdatesToInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.ApplyUpdatesToInstances(ctx, req, opts...)
+}
+
+// CreateInstances creates instances with per-instance configs in this regional managed instance group. Instances are created using the current instance template. The create instances operation is marked DONE if the createInstances request is successful. The underlying actions take additional time. You must separately verify the status of the creating or actions with the listmanagedinstances method.
+func (c *RegionInstanceGroupManagersClient) CreateInstances(ctx context.Context, req *computepb.CreateInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.CreateInstances(ctx, req, opts...)
+}
+
+// Delete deletes the specified managed instance group and all of the instances in that group.
+func (c *RegionInstanceGroupManagersClient) Delete(ctx context.Context, req *computepb.DeleteRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// DeleteInstances flags the specified instances in the managed instance group to be immediately deleted. The instances are also removed from any target pools of which they were a member. This method reduces the targetSize of the managed instance group by the number of instances that you delete. The deleteInstances operation is marked DONE if the deleteInstances request is successful. The underlying actions take additional time. You must separately verify the status of the deleting action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *RegionInstanceGroupManagersClient) DeleteInstances(ctx context.Context, req *computepb.DeleteInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeleteInstances(ctx, req, opts...)
+}
+
+// DeletePerInstanceConfigs deletes selected per-instance configs for the managed instance group.
+func (c *RegionInstanceGroupManagersClient) DeletePerInstanceConfigs(ctx context.Context, req *computepb.DeletePerInstanceConfigsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.DeletePerInstanceConfigs(ctx, req, opts...)
+}
+
+// Get returns all of the details about the specified managed instance group.
+func (c *RegionInstanceGroupManagersClient) Get(ctx context.Context, req *computepb.GetRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManager, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a managed instance group using the information that you specify in the request. After the group is created, instances in the group are created using the specified instance template. This operation is marked as DONE when the group is created even if the instances in the group have not yet been created. You must separately verify the status of the individual instances with the listmanagedinstances method.
+//
+// A regional managed instance group can contain up to 2000 instances.
+func (c *RegionInstanceGroupManagersClient) Insert(ctx context.Context, req *computepb.InsertRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of managed instance groups that are contained within the specified region.
+func (c *RegionInstanceGroupManagersClient) List(ctx context.Context, req *computepb.ListRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagerList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListErrors lists all errors thrown by actions on instances for a given regional managed instance group. The filter and orderBy query parameters are not supported.
+func (c *RegionInstanceGroupManagersClient) ListErrors(ctx context.Context, req *computepb.ListErrorsRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListErrorsResponse, error) {
+	return c.internalClient.ListErrors(ctx, req, opts...)
+}
+
+// ListManagedInstances lists the instances in the managed instance group and instances that are scheduled to be created. The list includes any current actions that the group has scheduled for its instances. The orderBy query parameter is not supported.
+func (c *RegionInstanceGroupManagersClient) ListManagedInstances(ctx context.Context, req *computepb.ListManagedInstancesRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListInstancesResponse, error) {
+	return c.internalClient.ListManagedInstances(ctx, req, opts...)
+}
+
+// ListPerInstanceConfigs lists all of the per-instance configs defined for the managed instance group. The orderBy query parameter is not supported.
+func (c *RegionInstanceGroupManagersClient) ListPerInstanceConfigs(ctx context.Context, req *computepb.ListPerInstanceConfigsRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListInstanceConfigsResp, error) {
+	return c.internalClient.ListPerInstanceConfigs(ctx, req, opts...)
+}
+
+// Patch updates a managed instance group using the information that you specify in the request. This operation is marked as DONE when the group is patched even if the instances in the group are still in the process of being patched. You must separately verify the status of the individual instances with the listmanagedinstances method. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *RegionInstanceGroupManagersClient) Patch(ctx context.Context, req *computepb.PatchRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// PatchPerInstanceConfigs inserts or patches per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *RegionInstanceGroupManagersClient) PatchPerInstanceConfigs(ctx context.Context, req *computepb.PatchPerInstanceConfigsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.PatchPerInstanceConfigs(ctx, req, opts...)
+}
+
+// RecreateInstances flags the specified VM instances in the managed instance group to be immediately recreated. Each instance is recreated using the group’s current configuration. This operation is marked as DONE when the flag is set even if the instances have not yet been recreated. You must separately verify the status of each instance by checking its currentAction field; for more information, see Checking the status of managed instances.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *RegionInstanceGroupManagersClient) RecreateInstances(ctx context.Context, req *computepb.RecreateInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RecreateInstances(ctx, req, opts...)
+}
+
+// Resize changes the intended size of the managed instance group. If you increase the size, the group creates new instances using the current instance template. If you decrease the size, the group deletes one or more instances.
+//
+// The resize operation is marked DONE if the resize request is successful. The underlying actions take additional time. You must separately verify the status of the creating or deleting actions with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+func (c *RegionInstanceGroupManagersClient) Resize(ctx context.Context, req *computepb.ResizeRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Resize(ctx, req, opts...)
+}
+
+// SetInstanceTemplate sets the instance template to use when creating new instances or recreating instances in this group. Existing instances are not affected.
+func (c *RegionInstanceGroupManagersClient) SetInstanceTemplate(ctx context.Context, req *computepb.SetInstanceTemplateRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetInstanceTemplate(ctx, req, opts...)
+}
+
+// SetTargetPools modifies the target pools to which all new instances in this group are assigned. Existing instances in the group are not affected.
+func (c *RegionInstanceGroupManagersClient) SetTargetPools(ctx context.Context, req *computepb.SetTargetPoolsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetTargetPools(ctx, req, opts...)
+}
+
+// UpdatePerInstanceConfigs inserts or updates per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *RegionInstanceGroupManagersClient) UpdatePerInstanceConfigs(ctx context.Context, req *computepb.UpdatePerInstanceConfigsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.UpdatePerInstanceConfigs(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionInstanceGroupManagersRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionInstanceGroupManagersRESTClient creates a new region instance group managers rest client.
+//
+// The RegionInstanceGroupManagers API.
+func NewRegionInstanceGroupManagersRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionInstanceGroupManagersClient, error) {
+	clientOpts := append(defaultRegionInstanceGroupManagersRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionInstanceGroupManagersRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionInstanceGroupManagersClient{internalClient: c, CallOptions: &RegionInstanceGroupManagersCallOptions{}}, nil
+}
+
+func defaultRegionInstanceGroupManagersRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionInstanceGroupManagersRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionInstanceGroupManagersRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionInstanceGroupManagersRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AbandonInstances flags the specified instances to be immediately removed from the managed instance group. Abandoning an instance does not delete the instance, but it does remove the instance from any target pools that are applied by the managed instance group. This method reduces the targetSize of the managed instance group by the number of instances that you abandon. This operation is marked as DONE when the action is scheduled even if the instances have not yet been removed from the group. You must separately verify the status of the abandoning action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *regionInstanceGroupManagersRESTClient) AbandonInstances(ctx context.Context, req *computepb.AbandonInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersAbandonInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/abandonInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ApplyUpdatesToInstances apply updates to selected instances the managed instance group.
+func (c *regionInstanceGroupManagersRESTClient) ApplyUpdatesToInstances(ctx context.Context, req *computepb.ApplyUpdatesToInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersApplyUpdatesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/applyUpdatesToInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// CreateInstances creates instances with per-instance configs in this regional managed instance group. Instances are created using the current instance template. The create instances operation is marked DONE if the createInstances request is successful. The underlying actions take additional time. You must separately verify the status of the creating or actions with the listmanagedinstances method.
+func (c *regionInstanceGroupManagersRESTClient) CreateInstances(ctx context.Context, req *computepb.CreateInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersCreateInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/createInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified managed instance group and all of the instances in that group.
+func (c *regionInstanceGroupManagersRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeleteInstances flags the specified instances in the managed instance group to be immediately deleted. The instances are also removed from any target pools of which they were a member. This method reduces the targetSize of the managed instance group by the number of instances that you delete. The deleteInstances operation is marked DONE if the deleteInstances request is successful. The underlying actions take additional time. You must separately verify the status of the deleting action with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *regionInstanceGroupManagersRESTClient) DeleteInstances(ctx context.Context, req *computepb.DeleteInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersDeleteInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/deleteInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// DeletePerInstanceConfigs deletes selected per-instance configs for the managed instance group.
+func (c *regionInstanceGroupManagersRESTClient) DeletePerInstanceConfigs(ctx context.Context, req *computepb.DeletePerInstanceConfigsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagerDeleteInstanceConfigReqResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/deletePerInstanceConfigs", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns all of the details about the specified managed instance group.
+func (c *regionInstanceGroupManagersRESTClient) Get(ctx context.Context, req *computepb.GetRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.InstanceGroupManager, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroupManager{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a managed instance group using the information that you specify in the request. After the group is created, instances in the group are created using the specified instance template. This operation is marked as DONE when the group is created even if the instances in the group have not yet been created. You must separately verify the status of the individual instances with the listmanagedinstances method.
+//
+// A regional managed instance group can contain up to 2000 instances.
+func (c *regionInstanceGroupManagersRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of managed instance groups that are contained within the specified region.
+func (c *regionInstanceGroupManagersRESTClient) List(ctx context.Context, req *computepb.ListRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagerList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionInstanceGroupManagerList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListErrors lists all errors thrown by actions on instances for a given regional managed instance group. The filter and orderBy query parameters are not supported.
+func (c *regionInstanceGroupManagersRESTClient) ListErrors(ctx context.Context, req *computepb.ListErrorsRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListErrorsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/listErrors", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionInstanceGroupManagersListErrorsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListManagedInstances lists the instances in the managed instance group and instances that are scheduled to be created. The list includes any current actions that the group has scheduled for its instances. The orderBy query parameter is not supported.
+func (c *regionInstanceGroupManagersRESTClient) ListManagedInstances(ctx context.Context, req *computepb.ListManagedInstancesRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListInstancesResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/listManagedInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionInstanceGroupManagersListInstancesResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListPerInstanceConfigs lists all of the per-instance configs defined for the managed instance group. The orderBy query parameter is not supported.
+func (c *regionInstanceGroupManagersRESTClient) ListPerInstanceConfigs(ctx context.Context, req *computepb.ListPerInstanceConfigsRegionInstanceGroupManagersRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupManagersListInstanceConfigsResp, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/listPerInstanceConfigs", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionInstanceGroupManagersListInstanceConfigsResp{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch updates a managed instance group using the information that you specify in the request. This operation is marked as DONE when the group is patched even if the instances in the group are still in the process of being patched. You must separately verify the status of the individual instances with the listmanagedinstances method. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *regionInstanceGroupManagersRESTClient) Patch(ctx context.Context, req *computepb.PatchRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceGroupManagerResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// PatchPerInstanceConfigs inserts or patches per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *regionInstanceGroupManagersRESTClient) PatchPerInstanceConfigs(ctx context.Context, req *computepb.PatchPerInstanceConfigsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagerPatchInstanceConfigReqResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/patchPerInstanceConfigs", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RecreateInstances flags the specified VM instances in the managed instance group to be immediately recreated. Each instance is recreated using the group’s current configuration. This operation is marked as DONE when the flag is set even if the instances have not yet been recreated. You must separately verify the status of each instance by checking its currentAction field; for more information, see Checking the status of managed instances.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+//
+// You can specify a maximum of 1000 instances with this method per request.
+func (c *regionInstanceGroupManagersRESTClient) RecreateInstances(ctx context.Context, req *computepb.RecreateInstancesRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersRecreateRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/recreateInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Resize changes the intended size of the managed instance group. If you increase the size, the group creates new instances using the current instance template. If you decrease the size, the group deletes one or more instances.
+//
+// The resize operation is marked DONE if the resize request is successful. The underlying actions take additional time. You must separately verify the status of the creating or deleting actions with the listmanagedinstances method.
+//
+// If the group is part of a backend service that has enabled connection draining, it can take up to 60 seconds after the connection draining duration has elapsed before the VM instance is removed or deleted.
+func (c *regionInstanceGroupManagersRESTClient) Resize(ctx context.Context, req *computepb.ResizeRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/resize", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetSize() != 0 {
+		params.Add("size", fmt.Sprintf("%v", req.GetSize()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetInstanceTemplate sets the instance template to use when creating new instances or recreating instances in this group. Existing instances are not affected.
+func (c *regionInstanceGroupManagersRESTClient) SetInstanceTemplate(ctx context.Context, req *computepb.SetInstanceTemplateRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersSetTemplateRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/setInstanceTemplate", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetTargetPools modifies the target pools to which all new instances in this group are assigned. Existing instances in the group are not affected.
+func (c *regionInstanceGroupManagersRESTClient) SetTargetPools(ctx context.Context, req *computepb.SetTargetPoolsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagersSetTargetPoolsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/setTargetPools", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// UpdatePerInstanceConfigs inserts or updates per-instance configs for the managed instance group. perInstanceConfig.name (at http://perInstanceConfig.name) serves as a key used to distinguish whether to perform insert or patch.
+func (c *regionInstanceGroupManagersRESTClient) UpdatePerInstanceConfigs(ctx context.Context, req *computepb.UpdatePerInstanceConfigsRegionInstanceGroupManagerRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupManagerUpdateInstanceConfigReqResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroupManagers/%v/updatePerInstanceConfigs", req.GetProject(), req.GetRegion(), req.GetInstanceGroupManager())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_instance_group_managers_client_example_test.go b/compute/apiv1/region_instance_group_managers_client_example_test.go
new file mode 100644
index 0000000..cf0c18b
--- /dev/null
+++ b/compute/apiv1/region_instance_group_managers_client_example_test.go
@@ -0,0 +1,397 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionInstanceGroupManagersRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionInstanceGroupManagersClient_AbandonInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AbandonInstancesRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AbandonInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_ApplyUpdatesToInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ApplyUpdatesToInstancesRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ApplyUpdatesToInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_CreateInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.CreateInstancesRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.CreateInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_DeleteInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteInstancesRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeleteInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_DeletePerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeletePerInstanceConfigsRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.DeletePerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_ListErrors() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListErrorsRegionInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListErrors(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_ListManagedInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListManagedInstancesRegionInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListManagedInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_ListPerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPerInstanceConfigsRegionInstanceGroupManagersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListPerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_PatchPerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchPerInstanceConfigsRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.PatchPerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_RecreateInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RecreateInstancesRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RecreateInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_Resize() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ResizeRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Resize(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_SetInstanceTemplate() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetInstanceTemplateRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetInstanceTemplate(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_SetTargetPools() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetTargetPoolsRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetTargetPools(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupManagersClient_UpdatePerInstanceConfigs() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupManagersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdatePerInstanceConfigsRegionInstanceGroupManagerRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.UpdatePerInstanceConfigs(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_instance_groups_client.go b/compute/apiv1/region_instance_groups_client.go
new file mode 100644
index 0000000..d2698ff
--- /dev/null
+++ b/compute/apiv1/region_instance_groups_client.go
@@ -0,0 +1,393 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionInstanceGroupsClientHook clientHook
+
+// RegionInstanceGroupsCallOptions contains the retry settings for each method of RegionInstanceGroupsClient.
+type RegionInstanceGroupsCallOptions struct {
+	Get           []gax.CallOption
+	List          []gax.CallOption
+	ListInstances []gax.CallOption
+	SetNamedPorts []gax.CallOption
+}
+
+// internalRegionInstanceGroupsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionInstanceGroupsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Get(context.Context, *computepb.GetRegionInstanceGroupRequest, ...gax.CallOption) (*computepb.InstanceGroup, error)
+	List(context.Context, *computepb.ListRegionInstanceGroupsRequest, ...gax.CallOption) (*computepb.RegionInstanceGroupList, error)
+	ListInstances(context.Context, *computepb.ListInstancesRegionInstanceGroupsRequest, ...gax.CallOption) (*computepb.RegionInstanceGroupsListInstances, error)
+	SetNamedPorts(context.Context, *computepb.SetNamedPortsRegionInstanceGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionInstanceGroupsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionInstanceGroups API.
+type RegionInstanceGroupsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionInstanceGroupsClient
+
+	// The call options for this service.
+	CallOptions *RegionInstanceGroupsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionInstanceGroupsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionInstanceGroupsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionInstanceGroupsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Get returns the specified instance group resource.
+func (c *RegionInstanceGroupsClient) Get(ctx context.Context, req *computepb.GetRegionInstanceGroupRequest, opts ...gax.CallOption) (*computepb.InstanceGroup, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves the list of instance group resources contained within the specified region.
+func (c *RegionInstanceGroupsClient) List(ctx context.Context, req *computepb.ListRegionInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListInstances lists the instances in the specified instance group and displays information about the named ports. Depending on the specified options, this method can list all instances or only the instances that are running. The orderBy query parameter is not supported.
+func (c *RegionInstanceGroupsClient) ListInstances(ctx context.Context, req *computepb.ListInstancesRegionInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupsListInstances, error) {
+	return c.internalClient.ListInstances(ctx, req, opts...)
+}
+
+// SetNamedPorts sets the named ports for the specified regional instance group.
+func (c *RegionInstanceGroupsClient) SetNamedPorts(ctx context.Context, req *computepb.SetNamedPortsRegionInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetNamedPorts(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionInstanceGroupsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionInstanceGroupsRESTClient creates a new region instance groups rest client.
+//
+// The RegionInstanceGroups API.
+func NewRegionInstanceGroupsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionInstanceGroupsClient, error) {
+	clientOpts := append(defaultRegionInstanceGroupsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionInstanceGroupsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionInstanceGroupsClient{internalClient: c, CallOptions: &RegionInstanceGroupsCallOptions{}}, nil
+}
+
+func defaultRegionInstanceGroupsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionInstanceGroupsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionInstanceGroupsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionInstanceGroupsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Get returns the specified instance group resource.
+func (c *regionInstanceGroupsRESTClient) Get(ctx context.Context, req *computepb.GetRegionInstanceGroupRequest, opts ...gax.CallOption) (*computepb.InstanceGroup, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroups/%v", req.GetProject(), req.GetRegion(), req.GetInstanceGroup())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.InstanceGroup{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of instance group resources contained within the specified region.
+func (c *regionInstanceGroupsRESTClient) List(ctx context.Context, req *computepb.ListRegionInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroups", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionInstanceGroupList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListInstances lists the instances in the specified instance group and displays information about the named ports. Depending on the specified options, this method can list all instances or only the instances that are running. The orderBy query parameter is not supported.
+func (c *regionInstanceGroupsRESTClient) ListInstances(ctx context.Context, req *computepb.ListInstancesRegionInstanceGroupsRequest, opts ...gax.CallOption) (*computepb.RegionInstanceGroupsListInstances, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupsListInstancesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroups/%v/listInstances", req.GetProject(), req.GetRegion(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionInstanceGroupsListInstances{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetNamedPorts sets the named ports for the specified regional instance group.
+func (c *regionInstanceGroupsRESTClient) SetNamedPorts(ctx context.Context, req *computepb.SetNamedPortsRegionInstanceGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionInstanceGroupsSetNamedPortsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instanceGroups/%v/setNamedPorts", req.GetProject(), req.GetRegion(), req.GetInstanceGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_instance_groups_client_example_test.go b/compute/apiv1/region_instance_groups_client_example_test.go
new file mode 100644
index 0000000..646c6f1
--- /dev/null
+++ b/compute/apiv1/region_instance_groups_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionInstanceGroupsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionInstanceGroupsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionInstanceGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupsClient_ListInstances() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListInstancesRegionInstanceGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListInstances(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionInstanceGroupsClient_SetNamedPorts() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstanceGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetNamedPortsRegionInstanceGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetNamedPorts(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_instances_client.go b/compute/apiv1/region_instances_client.go
new file mode 100644
index 0000000..e9a7f88
--- /dev/null
+++ b/compute/apiv1/region_instances_client.go
@@ -0,0 +1,204 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionInstancesClientHook clientHook
+
+// RegionInstancesCallOptions contains the retry settings for each method of RegionInstancesClient.
+type RegionInstancesCallOptions struct {
+	BulkInsert []gax.CallOption
+}
+
+// internalRegionInstancesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionInstancesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	BulkInsert(context.Context, *computepb.BulkInsertRegionInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionInstancesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionInstances API.
+type RegionInstancesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionInstancesClient
+
+	// The call options for this service.
+	CallOptions *RegionInstancesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionInstancesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionInstancesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionInstancesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// BulkInsert creates multiple instances in a given region. Count specifies the number of instances to create.
+func (c *RegionInstancesClient) BulkInsert(ctx context.Context, req *computepb.BulkInsertRegionInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.BulkInsert(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionInstancesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionInstancesRESTClient creates a new region instances rest client.
+//
+// The RegionInstances API.
+func NewRegionInstancesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionInstancesClient, error) {
+	clientOpts := append(defaultRegionInstancesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionInstancesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionInstancesClient{internalClient: c, CallOptions: &RegionInstancesCallOptions{}}, nil
+}
+
+func defaultRegionInstancesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionInstancesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionInstancesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionInstancesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// BulkInsert creates multiple instances in a given region. Count specifies the number of instances to create.
+func (c *regionInstancesRESTClient) BulkInsert(ctx context.Context, req *computepb.BulkInsertRegionInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetBulkInsertInstanceResourceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/instances/bulkInsert", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_instances_client_example_test.go b/compute/apiv1/region_instances_client_example_test.go
new file mode 100644
index 0000000..9856d6f
--- /dev/null
+++ b/compute/apiv1/region_instances_client_example_test.go
@@ -0,0 +1,55 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionInstancesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionInstancesClient_BulkInsert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.BulkInsertRegionInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.BulkInsert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_network_endpoint_groups_client.go b/compute/apiv1/region_network_endpoint_groups_client.go
new file mode 100644
index 0000000..ace6be5
--- /dev/null
+++ b/compute/apiv1/region_network_endpoint_groups_client.go
@@ -0,0 +1,380 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionNetworkEndpointGroupsClientHook clientHook
+
+// RegionNetworkEndpointGroupsCallOptions contains the retry settings for each method of RegionNetworkEndpointGroupsClient.
+type RegionNetworkEndpointGroupsCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+}
+
+// internalRegionNetworkEndpointGroupsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionNetworkEndpointGroupsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroup, error)
+	Insert(context.Context, *computepb.InsertRegionNetworkEndpointGroupRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionNetworkEndpointGroupsRequest, ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error)
+}
+
+// RegionNetworkEndpointGroupsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionNetworkEndpointGroups API.
+type RegionNetworkEndpointGroupsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionNetworkEndpointGroupsClient
+
+	// The call options for this service.
+	CallOptions *RegionNetworkEndpointGroupsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionNetworkEndpointGroupsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionNetworkEndpointGroupsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionNetworkEndpointGroupsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified network endpoint group. Note that the NEG cannot be deleted if it is configured as a backend of a backend service.
+func (c *RegionNetworkEndpointGroupsClient) Delete(ctx context.Context, req *computepb.DeleteRegionNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request.
+func (c *RegionNetworkEndpointGroupsClient) Get(ctx context.Context, req *computepb.GetRegionNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroup, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a network endpoint group in the specified project using the parameters that are included in the request.
+func (c *RegionNetworkEndpointGroupsClient) Insert(ctx context.Context, req *computepb.InsertRegionNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of regional network endpoint groups available to the specified project in the given region.
+func (c *RegionNetworkEndpointGroupsClient) List(ctx context.Context, req *computepb.ListRegionNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionNetworkEndpointGroupsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionNetworkEndpointGroupsRESTClient creates a new region network endpoint groups rest client.
+//
+// The RegionNetworkEndpointGroups API.
+func NewRegionNetworkEndpointGroupsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionNetworkEndpointGroupsClient, error) {
+	clientOpts := append(defaultRegionNetworkEndpointGroupsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionNetworkEndpointGroupsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionNetworkEndpointGroupsClient{internalClient: c, CallOptions: &RegionNetworkEndpointGroupsCallOptions{}}, nil
+}
+
+func defaultRegionNetworkEndpointGroupsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionNetworkEndpointGroupsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionNetworkEndpointGroupsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionNetworkEndpointGroupsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified network endpoint group. Note that the NEG cannot be deleted if it is configured as a backend of a backend service.
+func (c *regionNetworkEndpointGroupsRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/networkEndpointGroups/%v", req.GetProject(), req.GetRegion(), req.GetNetworkEndpointGroup())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified network endpoint group. Gets a list of available network endpoint groups by making a list() request.
+func (c *regionNetworkEndpointGroupsRESTClient) Get(ctx context.Context, req *computepb.GetRegionNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroup, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/networkEndpointGroups/%v", req.GetProject(), req.GetRegion(), req.GetNetworkEndpointGroup())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroup{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a network endpoint group in the specified project using the parameters that are included in the request.
+func (c *regionNetworkEndpointGroupsRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionNetworkEndpointGroupRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNetworkEndpointGroupResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/networkEndpointGroups", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of regional network endpoint groups available to the specified project in the given region.
+func (c *regionNetworkEndpointGroupsRESTClient) List(ctx context.Context, req *computepb.ListRegionNetworkEndpointGroupsRequest, opts ...gax.CallOption) (*computepb.NetworkEndpointGroupList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/networkEndpointGroups", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NetworkEndpointGroupList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_network_endpoint_groups_client_example_test.go b/compute/apiv1/region_network_endpoint_groups_client_example_test.go
new file mode 100644
index 0000000..507dcee
--- /dev/null
+++ b/compute/apiv1/region_network_endpoint_groups_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionNetworkEndpointGroupsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionNetworkEndpointGroupsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionNetworkEndpointGroupsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionNetworkEndpointGroupsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionNetworkEndpointGroupRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionNetworkEndpointGroupsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNetworkEndpointGroupsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionNetworkEndpointGroupsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_notification_endpoints_client.go b/compute/apiv1/region_notification_endpoints_client.go
new file mode 100644
index 0000000..1ab1648
--- /dev/null
+++ b/compute/apiv1/region_notification_endpoints_client.go
@@ -0,0 +1,380 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionNotificationEndpointsClientHook clientHook
+
+// RegionNotificationEndpointsCallOptions contains the retry settings for each method of RegionNotificationEndpointsClient.
+type RegionNotificationEndpointsCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+}
+
+// internalRegionNotificationEndpointsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionNotificationEndpointsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionNotificationEndpointRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionNotificationEndpointRequest, ...gax.CallOption) (*computepb.NotificationEndpoint, error)
+	Insert(context.Context, *computepb.InsertRegionNotificationEndpointRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionNotificationEndpointsRequest, ...gax.CallOption) (*computepb.NotificationEndpointList, error)
+}
+
+// RegionNotificationEndpointsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionNotificationEndpoints API.
+type RegionNotificationEndpointsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionNotificationEndpointsClient
+
+	// The call options for this service.
+	CallOptions *RegionNotificationEndpointsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionNotificationEndpointsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionNotificationEndpointsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionNotificationEndpointsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified NotificationEndpoint in the given region
+func (c *RegionNotificationEndpointsClient) Delete(ctx context.Context, req *computepb.DeleteRegionNotificationEndpointRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified NotificationEndpoint resource in the given region.
+func (c *RegionNotificationEndpointsClient) Get(ctx context.Context, req *computepb.GetRegionNotificationEndpointRequest, opts ...gax.CallOption) (*computepb.NotificationEndpoint, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert create a NotificationEndpoint in the specified project in the given region using the parameters that are included in the request.
+func (c *RegionNotificationEndpointsClient) Insert(ctx context.Context, req *computepb.InsertRegionNotificationEndpointRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists the NotificationEndpoints for a project in the given region.
+func (c *RegionNotificationEndpointsClient) List(ctx context.Context, req *computepb.ListRegionNotificationEndpointsRequest, opts ...gax.CallOption) (*computepb.NotificationEndpointList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionNotificationEndpointsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionNotificationEndpointsRESTClient creates a new region notification endpoints rest client.
+//
+// The RegionNotificationEndpoints API.
+func NewRegionNotificationEndpointsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionNotificationEndpointsClient, error) {
+	clientOpts := append(defaultRegionNotificationEndpointsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionNotificationEndpointsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionNotificationEndpointsClient{internalClient: c, CallOptions: &RegionNotificationEndpointsCallOptions{}}, nil
+}
+
+func defaultRegionNotificationEndpointsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionNotificationEndpointsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionNotificationEndpointsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionNotificationEndpointsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified NotificationEndpoint in the given region
+func (c *regionNotificationEndpointsRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionNotificationEndpointRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/notificationEndpoints/%v", req.GetProject(), req.GetRegion(), req.GetNotificationEndpoint())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified NotificationEndpoint resource in the given region.
+func (c *regionNotificationEndpointsRESTClient) Get(ctx context.Context, req *computepb.GetRegionNotificationEndpointRequest, opts ...gax.CallOption) (*computepb.NotificationEndpoint, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/notificationEndpoints/%v", req.GetProject(), req.GetRegion(), req.GetNotificationEndpoint())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NotificationEndpoint{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert create a NotificationEndpoint in the specified project in the given region using the parameters that are included in the request.
+func (c *regionNotificationEndpointsRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionNotificationEndpointRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetNotificationEndpointResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/notificationEndpoints", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists the NotificationEndpoints for a project in the given region.
+func (c *regionNotificationEndpointsRESTClient) List(ctx context.Context, req *computepb.ListRegionNotificationEndpointsRequest, opts ...gax.CallOption) (*computepb.NotificationEndpointList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/notificationEndpoints", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.NotificationEndpointList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_notification_endpoints_client_example_test.go b/compute/apiv1/region_notification_endpoints_client_example_test.go
new file mode 100644
index 0000000..7088519
--- /dev/null
+++ b/compute/apiv1/region_notification_endpoints_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionNotificationEndpointsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNotificationEndpointsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionNotificationEndpointsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNotificationEndpointsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionNotificationEndpointRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionNotificationEndpointsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNotificationEndpointsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionNotificationEndpointRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionNotificationEndpointsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNotificationEndpointsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionNotificationEndpointRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionNotificationEndpointsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionNotificationEndpointsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionNotificationEndpointsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_operations_client.go b/compute/apiv1/region_operations_client.go
new file mode 100644
index 0000000..cccff7a
--- /dev/null
+++ b/compute/apiv1/region_operations_client.go
@@ -0,0 +1,377 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionOperationsClientHook clientHook
+
+// RegionOperationsCallOptions contains the retry settings for each method of RegionOperationsClient.
+type RegionOperationsCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	List   []gax.CallOption
+	Wait   []gax.CallOption
+}
+
+// internalRegionOperationsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionOperationsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionOperationRequest, ...gax.CallOption) (*computepb.DeleteRegionOperationResponse, error)
+	Get(context.Context, *computepb.GetRegionOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionOperationsRequest, ...gax.CallOption) (*computepb.OperationList, error)
+	Wait(context.Context, *computepb.WaitRegionOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionOperationsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionOperations API.
+type RegionOperationsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionOperationsClient
+
+	// The call options for this service.
+	CallOptions *RegionOperationsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionOperationsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionOperationsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionOperationsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified region-specific Operations resource.
+func (c *RegionOperationsClient) Delete(ctx context.Context, req *computepb.DeleteRegionOperationRequest, opts ...gax.CallOption) (*computepb.DeleteRegionOperationResponse, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get retrieves the specified region-specific Operations resource.
+func (c *RegionOperationsClient) Get(ctx context.Context, req *computepb.GetRegionOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of Operation resources contained within the specified region.
+func (c *RegionOperationsClient) List(ctx context.Context, req *computepb.ListRegionOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Wait waits for the specified Operation resource to return as DONE or for the request to approach the 2 minute deadline, and retrieves the specified Operation resource. This method differs from the GET method in that it waits for no more than the default deadline (2 minutes) and then returns the current state of the operation, which might be DONE or still in progress.
+//
+// This method is called on a best-effort basis. Specifically:
+//
+//   In uncommon cases, when the server is overloaded, the request might return before the default deadline is reached, or might return after zero seconds.
+//
+//   If the default deadline is reached, there is no guarantee that the operation is actually done when the method returns. Be prepared to retry if the operation is not DONE.
+func (c *RegionOperationsClient) Wait(ctx context.Context, req *computepb.WaitRegionOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Wait(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionOperationsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionOperationsRESTClient creates a new region operations rest client.
+//
+// The RegionOperations API.
+func NewRegionOperationsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionOperationsClient, error) {
+	clientOpts := append(defaultRegionOperationsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionOperationsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionOperationsClient{internalClient: c, CallOptions: &RegionOperationsCallOptions{}}, nil
+}
+
+func defaultRegionOperationsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionOperationsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionOperationsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionOperationsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified region-specific Operations resource.
+func (c *regionOperationsRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionOperationRequest, opts ...gax.CallOption) (*computepb.DeleteRegionOperationResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/operations/%v", req.GetProject(), req.GetRegion(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DeleteRegionOperationResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get retrieves the specified region-specific Operations resource.
+func (c *regionOperationsRESTClient) Get(ctx context.Context, req *computepb.GetRegionOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/operations/%v", req.GetProject(), req.GetRegion(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of Operation resources contained within the specified region.
+func (c *regionOperationsRESTClient) List(ctx context.Context, req *computepb.ListRegionOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/operations", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.OperationList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Wait waits for the specified Operation resource to return as DONE or for the request to approach the 2 minute deadline, and retrieves the specified Operation resource. This method differs from the GET method in that it waits for no more than the default deadline (2 minutes) and then returns the current state of the operation, which might be DONE or still in progress.
+//
+// This method is called on a best-effort basis. Specifically:
+//
+//   In uncommon cases, when the server is overloaded, the request might return before the default deadline is reached, or might return after zero seconds.
+//
+//   If the default deadline is reached, there is no guarantee that the operation is actually done when the method returns. Be prepared to retry if the operation is not DONE.
+func (c *regionOperationsRESTClient) Wait(ctx context.Context, req *computepb.WaitRegionOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/operations/%v/wait", req.GetProject(), req.GetRegion(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_operations_client_example_test.go b/compute/apiv1/region_operations_client_example_test.go
new file mode 100644
index 0000000..75736e6
--- /dev/null
+++ b/compute/apiv1/region_operations_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionOperationsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionOperationsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionOperationsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionOperationsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionOperationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionOperationsClient_Wait() {
+	ctx := context.Background()
+	c, err := compute.NewRegionOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.WaitRegionOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Wait(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_ssl_certificates_client.go b/compute/apiv1/region_ssl_certificates_client.go
new file mode 100644
index 0000000..bcf0694
--- /dev/null
+++ b/compute/apiv1/region_ssl_certificates_client.go
@@ -0,0 +1,380 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionSslCertificatesClientHook clientHook
+
+// RegionSslCertificatesCallOptions contains the retry settings for each method of RegionSslCertificatesClient.
+type RegionSslCertificatesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+}
+
+// internalRegionSslCertificatesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionSslCertificatesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionSslCertificateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionSslCertificateRequest, ...gax.CallOption) (*computepb.SslCertificate, error)
+	Insert(context.Context, *computepb.InsertRegionSslCertificateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionSslCertificatesRequest, ...gax.CallOption) (*computepb.SslCertificateList, error)
+}
+
+// RegionSslCertificatesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionSslCertificates API.
+type RegionSslCertificatesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionSslCertificatesClient
+
+	// The call options for this service.
+	CallOptions *RegionSslCertificatesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionSslCertificatesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionSslCertificatesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionSslCertificatesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified SslCertificate resource in the region.
+func (c *RegionSslCertificatesClient) Delete(ctx context.Context, req *computepb.DeleteRegionSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified SslCertificate resource in the specified region. Get a list of available SSL certificates by making a list() request.
+func (c *RegionSslCertificatesClient) Get(ctx context.Context, req *computepb.GetRegionSslCertificateRequest, opts ...gax.CallOption) (*computepb.SslCertificate, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a SslCertificate resource in the specified project and region using the data included in the request
+func (c *RegionSslCertificatesClient) Insert(ctx context.Context, req *computepb.InsertRegionSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of SslCertificate resources available to the specified project in the specified region.
+func (c *RegionSslCertificatesClient) List(ctx context.Context, req *computepb.ListRegionSslCertificatesRequest, opts ...gax.CallOption) (*computepb.SslCertificateList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionSslCertificatesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionSslCertificatesRESTClient creates a new region ssl certificates rest client.
+//
+// The RegionSslCertificates API.
+func NewRegionSslCertificatesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionSslCertificatesClient, error) {
+	clientOpts := append(defaultRegionSslCertificatesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionSslCertificatesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionSslCertificatesClient{internalClient: c, CallOptions: &RegionSslCertificatesCallOptions{}}, nil
+}
+
+func defaultRegionSslCertificatesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionSslCertificatesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionSslCertificatesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionSslCertificatesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified SslCertificate resource in the region.
+func (c *regionSslCertificatesRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/sslCertificates/%v", req.GetProject(), req.GetRegion(), req.GetSslCertificate())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified SslCertificate resource in the specified region. Get a list of available SSL certificates by making a list() request.
+func (c *regionSslCertificatesRESTClient) Get(ctx context.Context, req *computepb.GetRegionSslCertificateRequest, opts ...gax.CallOption) (*computepb.SslCertificate, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/sslCertificates/%v", req.GetProject(), req.GetRegion(), req.GetSslCertificate())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslCertificate{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a SslCertificate resource in the specified project and region using the data included in the request
+func (c *regionSslCertificatesRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSslCertificateResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/sslCertificates", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of SslCertificate resources available to the specified project in the specified region.
+func (c *regionSslCertificatesRESTClient) List(ctx context.Context, req *computepb.ListRegionSslCertificatesRequest, opts ...gax.CallOption) (*computepb.SslCertificateList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/sslCertificates", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslCertificateList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_ssl_certificates_client_example_test.go b/compute/apiv1/region_ssl_certificates_client_example_test.go
new file mode 100644
index 0000000..016dcb9
--- /dev/null
+++ b/compute/apiv1/region_ssl_certificates_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionSslCertificatesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionSslCertificatesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionSslCertificateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionSslCertificatesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionSslCertificateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionSslCertificatesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionSslCertificateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionSslCertificatesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionSslCertificatesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_target_http_proxies_client.go b/compute/apiv1/region_target_http_proxies_client.go
new file mode 100644
index 0000000..f2a3388
--- /dev/null
+++ b/compute/apiv1/region_target_http_proxies_client.go
@@ -0,0 +1,438 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionTargetHttpProxiesClientHook clientHook
+
+// RegionTargetHttpProxiesCallOptions contains the retry settings for each method of RegionTargetHttpProxiesClient.
+type RegionTargetHttpProxiesCallOptions struct {
+	Delete    []gax.CallOption
+	Get       []gax.CallOption
+	Insert    []gax.CallOption
+	List      []gax.CallOption
+	SetUrlMap []gax.CallOption
+}
+
+// internalRegionTargetHttpProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionTargetHttpProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionTargetHttpProxyRequest, ...gax.CallOption) (*computepb.TargetHttpProxy, error)
+	Insert(context.Context, *computepb.InsertRegionTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionTargetHttpProxiesRequest, ...gax.CallOption) (*computepb.TargetHttpProxyList, error)
+	SetUrlMap(context.Context, *computepb.SetUrlMapRegionTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionTargetHttpProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionTargetHttpProxies API.
+type RegionTargetHttpProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionTargetHttpProxiesClient
+
+	// The call options for this service.
+	CallOptions *RegionTargetHttpProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionTargetHttpProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionTargetHttpProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionTargetHttpProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified TargetHttpProxy resource.
+func (c *RegionTargetHttpProxiesClient) Delete(ctx context.Context, req *computepb.DeleteRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetHttpProxy resource in the specified region. Gets a list of available target HTTP proxies by making a list() request.
+func (c *RegionTargetHttpProxiesClient) Get(ctx context.Context, req *computepb.GetRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetHttpProxy resource in the specified project and region using the data included in the request.
+func (c *RegionTargetHttpProxiesClient) Insert(ctx context.Context, req *computepb.InsertRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of TargetHttpProxy resources available to the specified project in the specified region.
+func (c *RegionTargetHttpProxiesClient) List(ctx context.Context, req *computepb.ListRegionTargetHttpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetUrlMap changes the URL map for TargetHttpProxy.
+func (c *RegionTargetHttpProxiesClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetUrlMap(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionTargetHttpProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionTargetHttpProxiesRESTClient creates a new region target http proxies rest client.
+//
+// The RegionTargetHttpProxies API.
+func NewRegionTargetHttpProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionTargetHttpProxiesClient, error) {
+	clientOpts := append(defaultRegionTargetHttpProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionTargetHttpProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionTargetHttpProxiesClient{internalClient: c, CallOptions: &RegionTargetHttpProxiesCallOptions{}}, nil
+}
+
+func defaultRegionTargetHttpProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionTargetHttpProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionTargetHttpProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionTargetHttpProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified TargetHttpProxy resource.
+func (c *regionTargetHttpProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpProxies/%v", req.GetProject(), req.GetRegion(), req.GetTargetHttpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetHttpProxy resource in the specified region. Gets a list of available target HTTP proxies by making a list() request.
+func (c *regionTargetHttpProxiesRESTClient) Get(ctx context.Context, req *computepb.GetRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpProxies/%v", req.GetProject(), req.GetRegion(), req.GetTargetHttpProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetHttpProxy resource in the specified project and region using the data included in the request.
+func (c *regionTargetHttpProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpProxies", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of TargetHttpProxy resources available to the specified project in the specified region.
+func (c *regionTargetHttpProxiesRESTClient) List(ctx context.Context, req *computepb.ListRegionTargetHttpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpProxies", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetUrlMap changes the URL map for TargetHttpProxy.
+func (c *regionTargetHttpProxiesRESTClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapRegionTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpProxies/%v/setUrlMap", req.GetProject(), req.GetRegion(), req.GetTargetHttpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_target_http_proxies_client_example_test.go b/compute/apiv1/region_target_http_proxies_client_example_test.go
new file mode 100644
index 0000000..0ccd58f
--- /dev/null
+++ b/compute/apiv1/region_target_http_proxies_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionTargetHttpProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionTargetHttpProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionTargetHttpProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpProxiesClient_SetUrlMap() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetUrlMapRegionTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetUrlMap(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_target_https_proxies_client.go b/compute/apiv1/region_target_https_proxies_client.go
new file mode 100644
index 0000000..af6c548
--- /dev/null
+++ b/compute/apiv1/region_target_https_proxies_client.go
@@ -0,0 +1,496 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionTargetHttpsProxiesClientHook clientHook
+
+// RegionTargetHttpsProxiesCallOptions contains the retry settings for each method of RegionTargetHttpsProxiesClient.
+type RegionTargetHttpsProxiesCallOptions struct {
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetSslCertificates []gax.CallOption
+	SetUrlMap          []gax.CallOption
+}
+
+// internalRegionTargetHttpsProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionTargetHttpsProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.TargetHttpsProxy, error)
+	Insert(context.Context, *computepb.InsertRegionTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionTargetHttpsProxiesRequest, ...gax.CallOption) (*computepb.TargetHttpsProxyList, error)
+	SetSslCertificates(context.Context, *computepb.SetSslCertificatesRegionTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetUrlMap(context.Context, *computepb.SetUrlMapRegionTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RegionTargetHttpsProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionTargetHttpsProxies API.
+type RegionTargetHttpsProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionTargetHttpsProxiesClient
+
+	// The call options for this service.
+	CallOptions *RegionTargetHttpsProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionTargetHttpsProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionTargetHttpsProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionTargetHttpsProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified TargetHttpsProxy resource.
+func (c *RegionTargetHttpsProxiesClient) Delete(ctx context.Context, req *computepb.DeleteRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetHttpsProxy resource in the specified region. Gets a list of available target HTTP proxies by making a list() request.
+func (c *RegionTargetHttpsProxiesClient) Get(ctx context.Context, req *computepb.GetRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetHttpsProxy resource in the specified project and region using the data included in the request.
+func (c *RegionTargetHttpsProxiesClient) Insert(ctx context.Context, req *computepb.InsertRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of TargetHttpsProxy resources available to the specified project in the specified region.
+func (c *RegionTargetHttpsProxiesClient) List(ctx context.Context, req *computepb.ListRegionTargetHttpsProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetSslCertificates replaces SslCertificates for TargetHttpsProxy.
+func (c *RegionTargetHttpsProxiesClient) SetSslCertificates(ctx context.Context, req *computepb.SetSslCertificatesRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetSslCertificates(ctx, req, opts...)
+}
+
+// SetUrlMap changes the URL map for TargetHttpsProxy.
+func (c *RegionTargetHttpsProxiesClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetUrlMap(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionTargetHttpsProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionTargetHttpsProxiesRESTClient creates a new region target https proxies rest client.
+//
+// The RegionTargetHttpsProxies API.
+func NewRegionTargetHttpsProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionTargetHttpsProxiesClient, error) {
+	clientOpts := append(defaultRegionTargetHttpsProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionTargetHttpsProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionTargetHttpsProxiesClient{internalClient: c, CallOptions: &RegionTargetHttpsProxiesCallOptions{}}, nil
+}
+
+func defaultRegionTargetHttpsProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionTargetHttpsProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionTargetHttpsProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionTargetHttpsProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified TargetHttpsProxy resource.
+func (c *regionTargetHttpsProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpsProxies/%v", req.GetProject(), req.GetRegion(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetHttpsProxy resource in the specified region. Gets a list of available target HTTP proxies by making a list() request.
+func (c *regionTargetHttpsProxiesRESTClient) Get(ctx context.Context, req *computepb.GetRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpsProxies/%v", req.GetProject(), req.GetRegion(), req.GetTargetHttpsProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpsProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetHttpsProxy resource in the specified project and region using the data included in the request.
+func (c *regionTargetHttpsProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpsProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpsProxies", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of TargetHttpsProxy resources available to the specified project in the specified region.
+func (c *regionTargetHttpsProxiesRESTClient) List(ctx context.Context, req *computepb.ListRegionTargetHttpsProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpsProxies", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpsProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetSslCertificates replaces SslCertificates for TargetHttpsProxy.
+func (c *regionTargetHttpsProxiesRESTClient) SetSslCertificates(ctx context.Context, req *computepb.SetSslCertificatesRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionTargetHttpsProxiesSetSslCertificatesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpsProxies/%v/setSslCertificates", req.GetProject(), req.GetRegion(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetUrlMap changes the URL map for TargetHttpsProxy.
+func (c *regionTargetHttpsProxiesRESTClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapRegionTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetHttpsProxies/%v/setUrlMap", req.GetProject(), req.GetRegion(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_target_https_proxies_client_example_test.go b/compute/apiv1/region_target_https_proxies_client_example_test.go
new file mode 100644
index 0000000..2e5ecb8
--- /dev/null
+++ b/compute/apiv1/region_target_https_proxies_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionTargetHttpsProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionTargetHttpsProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpsProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpsProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpsProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionTargetHttpsProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpsProxiesClient_SetSslCertificates() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSslCertificatesRegionTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetSslCertificates(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionTargetHttpsProxiesClient_SetUrlMap() {
+	ctx := context.Background()
+	c, err := compute.NewRegionTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetUrlMapRegionTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetUrlMap(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/region_url_maps_client.go b/compute/apiv1/region_url_maps_client.go
new file mode 100644
index 0000000..732c9c0
--- /dev/null
+++ b/compute/apiv1/region_url_maps_client.go
@@ -0,0 +1,556 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionUrlMapsClientHook clientHook
+
+// RegionUrlMapsCallOptions contains the retry settings for each method of RegionUrlMapsClient.
+type RegionUrlMapsCallOptions struct {
+	Delete   []gax.CallOption
+	Get      []gax.CallOption
+	Insert   []gax.CallOption
+	List     []gax.CallOption
+	Patch    []gax.CallOption
+	Update   []gax.CallOption
+	Validate []gax.CallOption
+}
+
+// internalRegionUrlMapsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionUrlMapsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRegionUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRegionUrlMapRequest, ...gax.CallOption) (*computepb.UrlMap, error)
+	Insert(context.Context, *computepb.InsertRegionUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRegionUrlMapsRequest, ...gax.CallOption) (*computepb.UrlMapList, error)
+	Patch(context.Context, *computepb.PatchRegionUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateRegionUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Validate(context.Context, *computepb.ValidateRegionUrlMapRequest, ...gax.CallOption) (*computepb.UrlMapsValidateResponse, error)
+}
+
+// RegionUrlMapsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The RegionUrlMaps API.
+type RegionUrlMapsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionUrlMapsClient
+
+	// The call options for this service.
+	CallOptions *RegionUrlMapsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionUrlMapsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionUrlMapsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionUrlMapsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified UrlMap resource.
+func (c *RegionUrlMapsClient) Delete(ctx context.Context, req *computepb.DeleteRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified UrlMap resource. Gets a list of available URL maps by making a list() request.
+func (c *RegionUrlMapsClient) Get(ctx context.Context, req *computepb.GetRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMap, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a UrlMap resource in the specified project using the data included in the request.
+func (c *RegionUrlMapsClient) Insert(ctx context.Context, req *computepb.InsertRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of UrlMap resources available to the specified project in the specified region.
+func (c *RegionUrlMapsClient) List(ctx context.Context, req *computepb.ListRegionUrlMapsRequest, opts ...gax.CallOption) (*computepb.UrlMapList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified UrlMap resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *RegionUrlMapsClient) Patch(ctx context.Context, req *computepb.PatchRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates the specified UrlMap resource with the data included in the request.
+func (c *RegionUrlMapsClient) Update(ctx context.Context, req *computepb.UpdateRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Validate runs static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap.
+func (c *RegionUrlMapsClient) Validate(ctx context.Context, req *computepb.ValidateRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMapsValidateResponse, error) {
+	return c.internalClient.Validate(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionUrlMapsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionUrlMapsRESTClient creates a new region url maps rest client.
+//
+// The RegionUrlMaps API.
+func NewRegionUrlMapsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionUrlMapsClient, error) {
+	clientOpts := append(defaultRegionUrlMapsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionUrlMapsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionUrlMapsClient{internalClient: c, CallOptions: &RegionUrlMapsCallOptions{}}, nil
+}
+
+func defaultRegionUrlMapsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionUrlMapsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionUrlMapsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionUrlMapsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified UrlMap resource.
+func (c *regionUrlMapsRESTClient) Delete(ctx context.Context, req *computepb.DeleteRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/urlMaps/%v", req.GetProject(), req.GetRegion(), req.GetUrlMap())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified UrlMap resource. Gets a list of available URL maps by making a list() request.
+func (c *regionUrlMapsRESTClient) Get(ctx context.Context, req *computepb.GetRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMap, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/urlMaps/%v", req.GetProject(), req.GetRegion(), req.GetUrlMap())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMap{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a UrlMap resource in the specified project using the data included in the request.
+func (c *regionUrlMapsRESTClient) Insert(ctx context.Context, req *computepb.InsertRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/urlMaps", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of UrlMap resources available to the specified project in the specified region.
+func (c *regionUrlMapsRESTClient) List(ctx context.Context, req *computepb.ListRegionUrlMapsRequest, opts ...gax.CallOption) (*computepb.UrlMapList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/urlMaps", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMapList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified UrlMap resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *regionUrlMapsRESTClient) Patch(ctx context.Context, req *computepb.PatchRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/urlMaps/%v", req.GetProject(), req.GetRegion(), req.GetUrlMap())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified UrlMap resource with the data included in the request.
+func (c *regionUrlMapsRESTClient) Update(ctx context.Context, req *computepb.UpdateRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req.GetRegion() != "" {
+		params.Add("region", fmt.Sprintf("%v", req.GetRegion()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetUrlMap() != "" {
+		params.Add("urlMap", fmt.Sprintf("%v", req.GetUrlMap()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Validate runs static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap.
+func (c *regionUrlMapsRESTClient) Validate(ctx context.Context, req *computepb.ValidateRegionUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMapsValidateResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionUrlMapsValidateRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/urlMaps/%v/validate", req.GetProject(), req.GetRegion(), req.GetUrlMap())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMapsValidateResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/region_url_maps_client_example_test.go b/compute/apiv1/region_url_maps_client_example_test.go
new file mode 100644
index 0000000..8a20f72
--- /dev/null
+++ b/compute/apiv1/region_url_maps_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionUrlMapsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionUrlMapsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRegionUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionUrlMapsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionUrlMapsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRegionUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionUrlMapsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionUrlMapsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionUrlMapsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRegionUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionUrlMapsClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateRegionUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionUrlMapsClient_Validate() {
+	ctx := context.Background()
+	c, err := compute.NewRegionUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ValidateRegionUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Validate(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/regions_client.go b/compute/apiv1/regions_client.go
new file mode 100644
index 0000000..9d26c40
--- /dev/null
+++ b/compute/apiv1/regions_client.go
@@ -0,0 +1,265 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRegionsClientHook clientHook
+
+// RegionsCallOptions contains the retry settings for each method of RegionsClient.
+type RegionsCallOptions struct {
+	Get  []gax.CallOption
+	List []gax.CallOption
+}
+
+// internalRegionsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRegionsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Get(context.Context, *computepb.GetRegionRequest, ...gax.CallOption) (*computepb.Region, error)
+	List(context.Context, *computepb.ListRegionsRequest, ...gax.CallOption) (*computepb.RegionList, error)
+}
+
+// RegionsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Regions API.
+type RegionsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRegionsClient
+
+	// The call options for this service.
+	CallOptions *RegionsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RegionsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RegionsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RegionsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Get returns the specified Region resource. Gets a list of available regions by making a list() request.
+func (c *RegionsClient) Get(ctx context.Context, req *computepb.GetRegionRequest, opts ...gax.CallOption) (*computepb.Region, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves the list of region resources available to the specified project.
+func (c *RegionsClient) List(ctx context.Context, req *computepb.ListRegionsRequest, opts ...gax.CallOption) (*computepb.RegionList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type regionsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRegionsRESTClient creates a new regions rest client.
+//
+// The Regions API.
+func NewRegionsRESTClient(ctx context.Context, opts ...option.ClientOption) (*RegionsClient, error) {
+	clientOpts := append(defaultRegionsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &regionsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RegionsClient{internalClient: c, CallOptions: &RegionsCallOptions{}}, nil
+}
+
+func defaultRegionsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *regionsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *regionsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *regionsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Get returns the specified Region resource. Gets a list of available regions by making a list() request.
+func (c *regionsRESTClient) Get(ctx context.Context, req *computepb.GetRegionRequest, opts ...gax.CallOption) (*computepb.Region, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v", req.GetProject(), req.GetRegion())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Region{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of region resources available to the specified project.
+func (c *regionsRESTClient) List(ctx context.Context, req *computepb.ListRegionsRequest, opts ...gax.CallOption) (*computepb.RegionList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RegionList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/regions_client_example_test.go b/compute/apiv1/regions_client_example_test.go
new file mode 100644
index 0000000..80af1fd
--- /dev/null
+++ b/compute/apiv1/regions_client_example_test.go
@@ -0,0 +1,74 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRegionsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRegionsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRegionsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRegionsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRegionRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRegionsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRegionsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRegionsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/reservations_client.go b/compute/apiv1/reservations_client.go
new file mode 100644
index 0000000..9c3cd71
--- /dev/null
+++ b/compute/apiv1/reservations_client.go
@@ -0,0 +1,669 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newReservationsClientHook clientHook
+
+// ReservationsCallOptions contains the retry settings for each method of ReservationsClient.
+type ReservationsCallOptions struct {
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	Resize             []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalReservationsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalReservationsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListReservationsRequest, ...gax.CallOption) (*computepb.ReservationAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteReservationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetReservationRequest, ...gax.CallOption) (*computepb.Reservation, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyReservationRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertReservationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListReservationsRequest, ...gax.CallOption) (*computepb.ReservationList, error)
+	Resize(context.Context, *computepb.ResizeReservationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyReservationRequest, ...gax.CallOption) (*computepb.Policy, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsReservationRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// ReservationsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Reservations API.
+type ReservationsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalReservationsClient
+
+	// The call options for this service.
+	CallOptions *ReservationsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ReservationsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ReservationsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ReservationsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of reservations.
+func (c *ReservationsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListReservationsRequest, opts ...gax.CallOption) (*computepb.ReservationAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified reservation.
+func (c *ReservationsClient) Delete(ctx context.Context, req *computepb.DeleteReservationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get retrieves information about the specified reservation.
+func (c *ReservationsClient) Get(ctx context.Context, req *computepb.GetReservationRequest, opts ...gax.CallOption) (*computepb.Reservation, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *ReservationsClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyReservationRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a new reservation. For more information, read Reserving zonal resources.
+func (c *ReservationsClient) Insert(ctx context.Context, req *computepb.InsertReservationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List a list of all the reservations that have been configured for the specified project in specified zone.
+func (c *ReservationsClient) List(ctx context.Context, req *computepb.ListReservationsRequest, opts ...gax.CallOption) (*computepb.ReservationList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Resize resizes the reservation (applicable to standalone reservations only). For more information, read Modifying reservations.
+func (c *ReservationsClient) Resize(ctx context.Context, req *computepb.ResizeReservationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Resize(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *ReservationsClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyReservationRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *ReservationsClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsReservationRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type reservationsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewReservationsRESTClient creates a new reservations rest client.
+//
+// The Reservations API.
+func NewReservationsRESTClient(ctx context.Context, opts ...option.ClientOption) (*ReservationsClient, error) {
+	clientOpts := append(defaultReservationsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &reservationsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ReservationsClient{internalClient: c, CallOptions: &ReservationsCallOptions{}}, nil
+}
+
+func defaultReservationsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *reservationsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *reservationsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *reservationsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of reservations.
+func (c *reservationsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListReservationsRequest, opts ...gax.CallOption) (*computepb.ReservationAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/reservations", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ReservationAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified reservation.
+func (c *reservationsRESTClient) Delete(ctx context.Context, req *computepb.DeleteReservationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations/%v", req.GetProject(), req.GetZone(), req.GetReservation())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get retrieves information about the specified reservation.
+func (c *reservationsRESTClient) Get(ctx context.Context, req *computepb.GetReservationRequest, opts ...gax.CallOption) (*computepb.Reservation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations/%v", req.GetProject(), req.GetZone(), req.GetReservation())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Reservation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *reservationsRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyReservationRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations/%v/getIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a new reservation. For more information, read Reserving zonal resources.
+func (c *reservationsRESTClient) Insert(ctx context.Context, req *computepb.InsertReservationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetReservationResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List a list of all the reservations that have been configured for the specified project in specified zone.
+func (c *reservationsRESTClient) List(ctx context.Context, req *computepb.ListReservationsRequest, opts ...gax.CallOption) (*computepb.ReservationList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ReservationList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Resize resizes the reservation (applicable to standalone reservations only). For more information, read Modifying reservations.
+func (c *reservationsRESTClient) Resize(ctx context.Context, req *computepb.ResizeReservationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetReservationsResizeRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations/%v/resize", req.GetProject(), req.GetZone(), req.GetReservation())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *reservationsRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyReservationRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetZoneSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations/%v/setIamPolicy", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *reservationsRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsReservationRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/reservations/%v/testIamPermissions", req.GetProject(), req.GetZone(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/reservations_client_example_test.go b/compute/apiv1/reservations_client_example_test.go
new file mode 100644
index 0000000..dda5436
--- /dev/null
+++ b/compute/apiv1/reservations_client_example_test.go
@@ -0,0 +1,207 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewReservationsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleReservationsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListReservationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListReservationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_Resize() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ResizeReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Resize(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleReservationsClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewReservationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsReservationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/resource_policies_client.go b/compute/apiv1/resource_policies_client.go
new file mode 100644
index 0000000..4e2b4d8
--- /dev/null
+++ b/compute/apiv1/resource_policies_client.go
@@ -0,0 +1,611 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newResourcePoliciesClientHook clientHook
+
+// ResourcePoliciesCallOptions contains the retry settings for each method of ResourcePoliciesClient.
+type ResourcePoliciesCallOptions struct {
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalResourcePoliciesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalResourcePoliciesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListResourcePoliciesRequest, ...gax.CallOption) (*computepb.ResourcePolicyAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteResourcePolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetResourcePolicyRequest, ...gax.CallOption) (*computepb.ResourcePolicy, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicyResourcePolicyRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertResourcePolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListResourcePoliciesRequest, ...gax.CallOption) (*computepb.ResourcePolicyList, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicyResourcePolicyRequest, ...gax.CallOption) (*computepb.Policy, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsResourcePolicyRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// ResourcePoliciesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The ResourcePolicies API.
+type ResourcePoliciesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalResourcePoliciesClient
+
+	// The call options for this service.
+	CallOptions *ResourcePoliciesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ResourcePoliciesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ResourcePoliciesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ResourcePoliciesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of resource policies.
+func (c *ResourcePoliciesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListResourcePoliciesRequest, opts ...gax.CallOption) (*computepb.ResourcePolicyAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified resource policy.
+func (c *ResourcePoliciesClient) Delete(ctx context.Context, req *computepb.DeleteResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get retrieves all information of the specified resource policy.
+func (c *ResourcePoliciesClient) Get(ctx context.Context, req *computepb.GetResourcePolicyRequest, opts ...gax.CallOption) (*computepb.ResourcePolicy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *ResourcePoliciesClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a new resource policy.
+func (c *ResourcePoliciesClient) Insert(ctx context.Context, req *computepb.InsertResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List a list all the resource policies that have been configured for the specified project in specified region.
+func (c *ResourcePoliciesClient) List(ctx context.Context, req *computepb.ListResourcePoliciesRequest, opts ...gax.CallOption) (*computepb.ResourcePolicyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *ResourcePoliciesClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *ResourcePoliciesClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsResourcePolicyRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type resourcePoliciesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewResourcePoliciesRESTClient creates a new resource policies rest client.
+//
+// The ResourcePolicies API.
+func NewResourcePoliciesRESTClient(ctx context.Context, opts ...option.ClientOption) (*ResourcePoliciesClient, error) {
+	clientOpts := append(defaultResourcePoliciesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &resourcePoliciesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ResourcePoliciesClient{internalClient: c, CallOptions: &ResourcePoliciesCallOptions{}}, nil
+}
+
+func defaultResourcePoliciesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *resourcePoliciesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *resourcePoliciesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *resourcePoliciesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of resource policies.
+func (c *resourcePoliciesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListResourcePoliciesRequest, opts ...gax.CallOption) (*computepb.ResourcePolicyAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/resourcePolicies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ResourcePolicyAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified resource policy.
+func (c *resourcePoliciesRESTClient) Delete(ctx context.Context, req *computepb.DeleteResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies/%v", req.GetProject(), req.GetRegion(), req.GetResourcePolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get retrieves all information of the specified resource policy.
+func (c *resourcePoliciesRESTClient) Get(ctx context.Context, req *computepb.GetResourcePolicyRequest, opts ...gax.CallOption) (*computepb.ResourcePolicy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies/%v", req.GetProject(), req.GetRegion(), req.GetResourcePolicy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ResourcePolicy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *resourcePoliciesRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicyResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies/%v/getIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a new resource policy.
+func (c *resourcePoliciesRESTClient) Insert(ctx context.Context, req *computepb.InsertResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetResourcePolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List a list all the resource policies that have been configured for the specified project in specified region.
+func (c *resourcePoliciesRESTClient) List(ctx context.Context, req *computepb.ListResourcePoliciesRequest, opts ...gax.CallOption) (*computepb.ResourcePolicyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ResourcePolicyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *resourcePoliciesRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicyResourcePolicyRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies/%v/setIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *resourcePoliciesRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsResourcePolicyRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/resourcePolicies/%v/testIamPermissions", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/resource_policies_client_example_test.go b/compute/apiv1/resource_policies_client_example_test.go
new file mode 100644
index 0000000..361e180
--- /dev/null
+++ b/compute/apiv1/resource_policies_client_example_test.go
@@ -0,0 +1,188 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewResourcePoliciesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleResourcePoliciesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListResourcePoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteResourcePolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetResourcePolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicyResourcePolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertResourcePolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListResourcePoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicyResourcePolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleResourcePoliciesClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewResourcePoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsResourcePolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/routers_client.go b/compute/apiv1/routers_client.go
new file mode 100644
index 0000000..b454d17
--- /dev/null
+++ b/compute/apiv1/routers_client.go
@@ -0,0 +1,747 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRoutersClientHook clientHook
+
+// RoutersCallOptions contains the retry settings for each method of RoutersClient.
+type RoutersCallOptions struct {
+	AggregatedList    []gax.CallOption
+	Delete            []gax.CallOption
+	Get               []gax.CallOption
+	GetNatMappingInfo []gax.CallOption
+	GetRouterStatus   []gax.CallOption
+	Insert            []gax.CallOption
+	List              []gax.CallOption
+	Patch             []gax.CallOption
+	Preview           []gax.CallOption
+	Update            []gax.CallOption
+}
+
+// internalRoutersClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRoutersClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListRoutersRequest, ...gax.CallOption) (*computepb.RouterAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteRouterRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRouterRequest, ...gax.CallOption) (*computepb.Router, error)
+	GetNatMappingInfo(context.Context, *computepb.GetNatMappingInfoRoutersRequest, ...gax.CallOption) (*computepb.VmEndpointNatMappingsList, error)
+	GetRouterStatus(context.Context, *computepb.GetRouterStatusRouterRequest, ...gax.CallOption) (*computepb.RouterStatusResponse, error)
+	Insert(context.Context, *computepb.InsertRouterRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRoutersRequest, ...gax.CallOption) (*computepb.RouterList, error)
+	Patch(context.Context, *computepb.PatchRouterRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Preview(context.Context, *computepb.PreviewRouterRequest, ...gax.CallOption) (*computepb.RoutersPreviewResponse, error)
+	Update(context.Context, *computepb.UpdateRouterRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// RoutersClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Routers API.
+type RoutersClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRoutersClient
+
+	// The call options for this service.
+	CallOptions *RoutersCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RoutersClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RoutersClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RoutersClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of routers.
+func (c *RoutersClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListRoutersRequest, opts ...gax.CallOption) (*computepb.RouterAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified Router resource.
+func (c *RoutersClient) Delete(ctx context.Context, req *computepb.DeleteRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified Router resource. Gets a list of available routers by making a list() request.
+func (c *RoutersClient) Get(ctx context.Context, req *computepb.GetRouterRequest, opts ...gax.CallOption) (*computepb.Router, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetNatMappingInfo retrieves runtime Nat mapping information of VM endpoints.
+func (c *RoutersClient) GetNatMappingInfo(ctx context.Context, req *computepb.GetNatMappingInfoRoutersRequest, opts ...gax.CallOption) (*computepb.VmEndpointNatMappingsList, error) {
+	return c.internalClient.GetNatMappingInfo(ctx, req, opts...)
+}
+
+// GetRouterStatus retrieves runtime information of the specified router.
+func (c *RoutersClient) GetRouterStatus(ctx context.Context, req *computepb.GetRouterStatusRouterRequest, opts ...gax.CallOption) (*computepb.RouterStatusResponse, error) {
+	return c.internalClient.GetRouterStatus(ctx, req, opts...)
+}
+
+// Insert creates a Router resource in the specified project and region using the data included in the request.
+func (c *RoutersClient) Insert(ctx context.Context, req *computepb.InsertRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of Router resources available to the specified project.
+func (c *RoutersClient) List(ctx context.Context, req *computepb.ListRoutersRequest, opts ...gax.CallOption) (*computepb.RouterList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified Router resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *RoutersClient) Patch(ctx context.Context, req *computepb.PatchRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Preview preview fields auto-generated during router create and update operations. Calling this method does NOT create or update the router.
+func (c *RoutersClient) Preview(ctx context.Context, req *computepb.PreviewRouterRequest, opts ...gax.CallOption) (*computepb.RoutersPreviewResponse, error) {
+	return c.internalClient.Preview(ctx, req, opts...)
+}
+
+// Update updates the specified Router resource with the data included in the request. This method conforms to PUT semantics, which requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.
+func (c *RoutersClient) Update(ctx context.Context, req *computepb.UpdateRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type routersRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRoutersRESTClient creates a new routers rest client.
+//
+// The Routers API.
+func NewRoutersRESTClient(ctx context.Context, opts ...option.ClientOption) (*RoutersClient, error) {
+	clientOpts := append(defaultRoutersRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &routersRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RoutersClient{internalClient: c, CallOptions: &RoutersCallOptions{}}, nil
+}
+
+func defaultRoutersRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *routersRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *routersRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *routersRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of routers.
+func (c *routersRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListRoutersRequest, opts ...gax.CallOption) (*computepb.RouterAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/routers", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RouterAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified Router resource.
+func (c *routersRESTClient) Delete(ctx context.Context, req *computepb.DeleteRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers/%v", req.GetProject(), req.GetRegion(), req.GetRouter())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified Router resource. Gets a list of available routers by making a list() request.
+func (c *routersRESTClient) Get(ctx context.Context, req *computepb.GetRouterRequest, opts ...gax.CallOption) (*computepb.Router, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers/%v", req.GetProject(), req.GetRegion(), req.GetRouter())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Router{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetNatMappingInfo retrieves runtime Nat mapping information of VM endpoints.
+func (c *routersRESTClient) GetNatMappingInfo(ctx context.Context, req *computepb.GetNatMappingInfoRoutersRequest, opts ...gax.CallOption) (*computepb.VmEndpointNatMappingsList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers/%v/getNatMappingInfo", req.GetProject(), req.GetRegion(), req.GetRouter())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VmEndpointNatMappingsList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetRouterStatus retrieves runtime information of the specified router.
+func (c *routersRESTClient) GetRouterStatus(ctx context.Context, req *computepb.GetRouterStatusRouterRequest, opts ...gax.CallOption) (*computepb.RouterStatusResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers/%v/getRouterStatus", req.GetProject(), req.GetRegion(), req.GetRouter())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RouterStatusResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a Router resource in the specified project and region using the data included in the request.
+func (c *routersRESTClient) Insert(ctx context.Context, req *computepb.InsertRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRouterResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of Router resources available to the specified project.
+func (c *routersRESTClient) List(ctx context.Context, req *computepb.ListRoutersRequest, opts ...gax.CallOption) (*computepb.RouterList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RouterList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified Router resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *routersRESTClient) Patch(ctx context.Context, req *computepb.PatchRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRouterResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers/%v", req.GetProject(), req.GetRegion(), req.GetRouter())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Preview preview fields auto-generated during router create and update operations. Calling this method does NOT create or update the router.
+func (c *routersRESTClient) Preview(ctx context.Context, req *computepb.PreviewRouterRequest, opts ...gax.CallOption) (*computepb.RoutersPreviewResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRouterResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/routers/%v/preview", req.GetProject(), req.GetRegion(), req.GetRouter())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RoutersPreviewResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified Router resource with the data included in the request. This method conforms to PUT semantics, which requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.
+func (c *routersRESTClient) Update(ctx context.Context, req *computepb.UpdateRouterRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRouterResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req.GetRegion() != "" {
+		params.Add("region", fmt.Sprintf("%v", req.GetRegion()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetRouter() != "" {
+		params.Add("router", fmt.Sprintf("%v", req.GetRouter()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/routers_client_example_test.go b/compute/apiv1/routers_client_example_test.go
new file mode 100644
index 0000000..96553d9
--- /dev/null
+++ b/compute/apiv1/routers_client_example_test.go
@@ -0,0 +1,226 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRoutersRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRoutersClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListRoutersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_GetNatMappingInfo() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetNatMappingInfoRoutersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetNatMappingInfo(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_GetRouterStatus() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRouterStatusRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetRouterStatus(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRoutersRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_Preview() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PreviewRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Preview(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutersClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewRoutersRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateRouterRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/routes_client.go b/compute/apiv1/routes_client.go
new file mode 100644
index 0000000..cd8f909
--- /dev/null
+++ b/compute/apiv1/routes_client.go
@@ -0,0 +1,380 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newRoutesClientHook clientHook
+
+// RoutesCallOptions contains the retry settings for each method of RoutesClient.
+type RoutesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+}
+
+// internalRoutesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalRoutesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteRouteRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetRouteRequest, ...gax.CallOption) (*computepb.Route, error)
+	Insert(context.Context, *computepb.InsertRouteRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListRoutesRequest, ...gax.CallOption) (*computepb.RouteList, error)
+}
+
+// RoutesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Routes API.
+type RoutesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalRoutesClient
+
+	// The call options for this service.
+	CallOptions *RoutesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *RoutesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *RoutesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *RoutesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified Route resource.
+func (c *RoutesClient) Delete(ctx context.Context, req *computepb.DeleteRouteRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified Route resource. Gets a list of available routes by making a list() request.
+func (c *RoutesClient) Get(ctx context.Context, req *computepb.GetRouteRequest, opts ...gax.CallOption) (*computepb.Route, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a Route resource in the specified project using the data included in the request.
+func (c *RoutesClient) Insert(ctx context.Context, req *computepb.InsertRouteRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of Route resources available to the specified project.
+func (c *RoutesClient) List(ctx context.Context, req *computepb.ListRoutesRequest, opts ...gax.CallOption) (*computepb.RouteList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type routesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewRoutesRESTClient creates a new routes rest client.
+//
+// The Routes API.
+func NewRoutesRESTClient(ctx context.Context, opts ...option.ClientOption) (*RoutesClient, error) {
+	clientOpts := append(defaultRoutesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &routesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &RoutesClient{internalClient: c, CallOptions: &RoutesCallOptions{}}, nil
+}
+
+func defaultRoutesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *routesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *routesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *routesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified Route resource.
+func (c *routesRESTClient) Delete(ctx context.Context, req *computepb.DeleteRouteRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/routes/%v", req.GetProject(), req.GetRoute())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified Route resource. Gets a list of available routes by making a list() request.
+func (c *routesRESTClient) Get(ctx context.Context, req *computepb.GetRouteRequest, opts ...gax.CallOption) (*computepb.Route, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/routes/%v", req.GetProject(), req.GetRoute())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Route{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a Route resource in the specified project using the data included in the request.
+func (c *routesRESTClient) Insert(ctx context.Context, req *computepb.InsertRouteRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRouteResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/routes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of Route resources available to the specified project.
+func (c *routesRESTClient) List(ctx context.Context, req *computepb.ListRoutesRequest, opts ...gax.CallOption) (*computepb.RouteList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/routes", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.RouteList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/routes_client_example_test.go b/compute/apiv1/routes_client_example_test.go
new file mode 100644
index 0000000..7303547
--- /dev/null
+++ b/compute/apiv1/routes_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewRoutesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewRoutesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleRoutesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewRoutesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteRouteRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewRoutesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRouteRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewRoutesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertRouteRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleRoutesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewRoutesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListRoutesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/security_policies_client.go b/compute/apiv1/security_policies_client.go
new file mode 100644
index 0000000..fceb165
--- /dev/null
+++ b/compute/apiv1/security_policies_client.go
@@ -0,0 +1,730 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newSecurityPoliciesClientHook clientHook
+
+// SecurityPoliciesCallOptions contains the retry settings for each method of SecurityPoliciesClient.
+type SecurityPoliciesCallOptions struct {
+	AddRule                         []gax.CallOption
+	Delete                          []gax.CallOption
+	Get                             []gax.CallOption
+	GetRule                         []gax.CallOption
+	Insert                          []gax.CallOption
+	List                            []gax.CallOption
+	ListPreconfiguredExpressionSets []gax.CallOption
+	Patch                           []gax.CallOption
+	PatchRule                       []gax.CallOption
+	RemoveRule                      []gax.CallOption
+}
+
+// internalSecurityPoliciesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalSecurityPoliciesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddRule(context.Context, *computepb.AddRuleSecurityPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Delete(context.Context, *computepb.DeleteSecurityPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetSecurityPolicyRequest, ...gax.CallOption) (*computepb.SecurityPolicy, error)
+	GetRule(context.Context, *computepb.GetRuleSecurityPolicyRequest, ...gax.CallOption) (*computepb.SecurityPolicyRule, error)
+	Insert(context.Context, *computepb.InsertSecurityPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListSecurityPoliciesRequest, ...gax.CallOption) (*computepb.SecurityPolicyList, error)
+	ListPreconfiguredExpressionSets(context.Context, *computepb.ListPreconfiguredExpressionSetsSecurityPoliciesRequest, ...gax.CallOption) (*computepb.SecurityPoliciesListPreconfiguredExpressionSetsResponse, error)
+	Patch(context.Context, *computepb.PatchSecurityPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	PatchRule(context.Context, *computepb.PatchRuleSecurityPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RemoveRule(context.Context, *computepb.RemoveRuleSecurityPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// SecurityPoliciesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The SecurityPolicies API.
+type SecurityPoliciesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalSecurityPoliciesClient
+
+	// The call options for this service.
+	CallOptions *SecurityPoliciesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *SecurityPoliciesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *SecurityPoliciesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *SecurityPoliciesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddRule inserts a rule into a security policy.
+func (c *SecurityPoliciesClient) AddRule(ctx context.Context, req *computepb.AddRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddRule(ctx, req, opts...)
+}
+
+// Delete deletes the specified policy.
+func (c *SecurityPoliciesClient) Delete(ctx context.Context, req *computepb.DeleteSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get list all of the ordered rules present in a single specified policy.
+func (c *SecurityPoliciesClient) Get(ctx context.Context, req *computepb.GetSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.SecurityPolicy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetRule gets a rule at the specified priority.
+func (c *SecurityPoliciesClient) GetRule(ctx context.Context, req *computepb.GetRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.SecurityPolicyRule, error) {
+	return c.internalClient.GetRule(ctx, req, opts...)
+}
+
+// Insert creates a new policy in the specified project using the data included in the request.
+func (c *SecurityPoliciesClient) Insert(ctx context.Context, req *computepb.InsertSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List list all the policies that have been configured for the specified project.
+func (c *SecurityPoliciesClient) List(ctx context.Context, req *computepb.ListSecurityPoliciesRequest, opts ...gax.CallOption) (*computepb.SecurityPolicyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListPreconfiguredExpressionSets gets the current list of preconfigured Web Application Firewall (WAF) expressions.
+func (c *SecurityPoliciesClient) ListPreconfiguredExpressionSets(ctx context.Context, req *computepb.ListPreconfiguredExpressionSetsSecurityPoliciesRequest, opts ...gax.CallOption) (*computepb.SecurityPoliciesListPreconfiguredExpressionSetsResponse, error) {
+	return c.internalClient.ListPreconfiguredExpressionSets(ctx, req, opts...)
+}
+
+// Patch patches the specified policy with the data included in the request. This cannot be used to be update the rules in the policy. Please use the per rule methods like addRule, patchRule, and removeRule instead.
+func (c *SecurityPoliciesClient) Patch(ctx context.Context, req *computepb.PatchSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// PatchRule patches a rule at the specified priority.
+func (c *SecurityPoliciesClient) PatchRule(ctx context.Context, req *computepb.PatchRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.PatchRule(ctx, req, opts...)
+}
+
+// RemoveRule deletes a rule at the specified priority.
+func (c *SecurityPoliciesClient) RemoveRule(ctx context.Context, req *computepb.RemoveRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveRule(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type securityPoliciesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewSecurityPoliciesRESTClient creates a new security policies rest client.
+//
+// The SecurityPolicies API.
+func NewSecurityPoliciesRESTClient(ctx context.Context, opts ...option.ClientOption) (*SecurityPoliciesClient, error) {
+	clientOpts := append(defaultSecurityPoliciesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &securityPoliciesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &SecurityPoliciesClient{internalClient: c, CallOptions: &SecurityPoliciesCallOptions{}}, nil
+}
+
+func defaultSecurityPoliciesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *securityPoliciesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *securityPoliciesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *securityPoliciesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddRule inserts a rule into a security policy.
+func (c *securityPoliciesRESTClient) AddRule(ctx context.Context, req *computepb.AddRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSecurityPolicyRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v/addRule", req.GetProject(), req.GetSecurityPolicy())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified policy.
+func (c *securityPoliciesRESTClient) Delete(ctx context.Context, req *computepb.DeleteSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v", req.GetProject(), req.GetSecurityPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get list all of the ordered rules present in a single specified policy.
+func (c *securityPoliciesRESTClient) Get(ctx context.Context, req *computepb.GetSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.SecurityPolicy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v", req.GetProject(), req.GetSecurityPolicy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SecurityPolicy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetRule gets a rule at the specified priority.
+func (c *securityPoliciesRESTClient) GetRule(ctx context.Context, req *computepb.GetRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.SecurityPolicyRule, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v/getRule", req.GetProject(), req.GetSecurityPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Priority != nil {
+		params.Add("priority", fmt.Sprintf("%v", req.GetPriority()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SecurityPolicyRule{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a new policy in the specified project using the data included in the request.
+func (c *securityPoliciesRESTClient) Insert(ctx context.Context, req *computepb.InsertSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSecurityPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List list all the policies that have been configured for the specified project.
+func (c *securityPoliciesRESTClient) List(ctx context.Context, req *computepb.ListSecurityPoliciesRequest, opts ...gax.CallOption) (*computepb.SecurityPolicyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SecurityPolicyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListPreconfiguredExpressionSets gets the current list of preconfigured Web Application Firewall (WAF) expressions.
+func (c *securityPoliciesRESTClient) ListPreconfiguredExpressionSets(ctx context.Context, req *computepb.ListPreconfiguredExpressionSetsSecurityPoliciesRequest, opts ...gax.CallOption) (*computepb.SecurityPoliciesListPreconfiguredExpressionSetsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/listPreconfiguredExpressionSets", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SecurityPoliciesListPreconfiguredExpressionSetsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified policy with the data included in the request. This cannot be used to be update the rules in the policy. Please use the per rule methods like addRule, patchRule, and removeRule instead.
+func (c *securityPoliciesRESTClient) Patch(ctx context.Context, req *computepb.PatchSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSecurityPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v", req.GetProject(), req.GetSecurityPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// PatchRule patches a rule at the specified priority.
+func (c *securityPoliciesRESTClient) PatchRule(ctx context.Context, req *computepb.PatchRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSecurityPolicyRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v/patchRule", req.GetProject(), req.GetSecurityPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Priority != nil {
+		params.Add("priority", fmt.Sprintf("%v", req.GetPriority()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveRule deletes a rule at the specified priority.
+func (c *securityPoliciesRESTClient) RemoveRule(ctx context.Context, req *computepb.RemoveRuleSecurityPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/securityPolicies/%v/removeRule", req.GetProject(), req.GetSecurityPolicy())
+
+	params := url.Values{}
+	if req != nil && req.Priority != nil {
+		params.Add("priority", fmt.Sprintf("%v", req.GetPriority()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/security_policies_client_example_test.go b/compute/apiv1/security_policies_client_example_test.go
new file mode 100644
index 0000000..65dbeb4
--- /dev/null
+++ b/compute/apiv1/security_policies_client_example_test.go
@@ -0,0 +1,226 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewSecurityPoliciesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleSecurityPoliciesClient_AddRule() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddRuleSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_GetRule() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetRuleSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListSecurityPoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_ListPreconfiguredExpressionSets() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListPreconfiguredExpressionSetsSecurityPoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListPreconfiguredExpressionSets(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_PatchRule() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchRuleSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.PatchRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSecurityPoliciesClient_RemoveRule() {
+	ctx := context.Background()
+	c, err := compute.NewSecurityPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveRuleSecurityPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveRule(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/snapshots_client.go b/compute/apiv1/snapshots_client.go
new file mode 100644
index 0000000..d95bf38
--- /dev/null
+++ b/compute/apiv1/snapshots_client.go
@@ -0,0 +1,536 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newSnapshotsClientHook clientHook
+
+// SnapshotsCallOptions contains the retry settings for each method of SnapshotsClient.
+type SnapshotsCallOptions struct {
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetIamPolicy       []gax.CallOption
+	List               []gax.CallOption
+	SetIamPolicy       []gax.CallOption
+	SetLabels          []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalSnapshotsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalSnapshotsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteSnapshotRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetSnapshotRequest, ...gax.CallOption) (*computepb.Snapshot, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicySnapshotRequest, ...gax.CallOption) (*computepb.Policy, error)
+	List(context.Context, *computepb.ListSnapshotsRequest, ...gax.CallOption) (*computepb.SnapshotList, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicySnapshotRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetLabels(context.Context, *computepb.SetLabelsSnapshotRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsSnapshotRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// SnapshotsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Snapshots API.
+type SnapshotsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalSnapshotsClient
+
+	// The call options for this service.
+	CallOptions *SnapshotsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *SnapshotsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *SnapshotsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *SnapshotsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified Snapshot resource. Keep in mind that deleting a single snapshot might not necessarily delete all the data on that snapshot. If any data on the snapshot that is marked for deletion is needed for subsequent snapshots, the data will be moved to the next corresponding snapshot.
+//
+// For more information, see Deleting snapshots.
+func (c *SnapshotsClient) Delete(ctx context.Context, req *computepb.DeleteSnapshotRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified Snapshot resource. Gets a list of available snapshots by making a list() request.
+func (c *SnapshotsClient) Get(ctx context.Context, req *computepb.GetSnapshotRequest, opts ...gax.CallOption) (*computepb.Snapshot, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *SnapshotsClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicySnapshotRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// List retrieves the list of Snapshot resources contained within the specified project.
+func (c *SnapshotsClient) List(ctx context.Context, req *computepb.ListSnapshotsRequest, opts ...gax.CallOption) (*computepb.SnapshotList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *SnapshotsClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicySnapshotRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on a snapshot. To learn more about labels, read the Labeling Resources documentation.
+func (c *SnapshotsClient) SetLabels(ctx context.Context, req *computepb.SetLabelsSnapshotRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *SnapshotsClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsSnapshotRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type snapshotsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewSnapshotsRESTClient creates a new snapshots rest client.
+//
+// The Snapshots API.
+func NewSnapshotsRESTClient(ctx context.Context, opts ...option.ClientOption) (*SnapshotsClient, error) {
+	clientOpts := append(defaultSnapshotsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &snapshotsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &SnapshotsClient{internalClient: c, CallOptions: &SnapshotsCallOptions{}}, nil
+}
+
+func defaultSnapshotsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *snapshotsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *snapshotsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *snapshotsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified Snapshot resource. Keep in mind that deleting a single snapshot might not necessarily delete all the data on that snapshot. If any data on the snapshot that is marked for deletion is needed for subsequent snapshots, the data will be moved to the next corresponding snapshot.
+//
+// For more information, see Deleting snapshots.
+func (c *snapshotsRESTClient) Delete(ctx context.Context, req *computepb.DeleteSnapshotRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots/%v", req.GetProject(), req.GetSnapshot())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified Snapshot resource. Gets a list of available snapshots by making a list() request.
+func (c *snapshotsRESTClient) Get(ctx context.Context, req *computepb.GetSnapshotRequest, opts ...gax.CallOption) (*computepb.Snapshot, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots/%v", req.GetProject(), req.GetSnapshot())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Snapshot{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *snapshotsRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicySnapshotRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots/%v/getIamPolicy", req.GetProject(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of Snapshot resources contained within the specified project.
+func (c *snapshotsRESTClient) List(ctx context.Context, req *computepb.ListSnapshotsRequest, opts ...gax.CallOption) (*computepb.SnapshotList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SnapshotList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *snapshotsRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicySnapshotRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots/%v/setIamPolicy", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on a snapshot. To learn more about labels, read the Labeling Resources documentation.
+func (c *snapshotsRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsSnapshotRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetGlobalSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots/%v/setLabels", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *snapshotsRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsSnapshotRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/snapshots/%v/testIamPermissions", req.GetProject(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/snapshots_client_example_test.go b/compute/apiv1/snapshots_client_example_test.go
new file mode 100644
index 0000000..ebdb2d2
--- /dev/null
+++ b/compute/apiv1/snapshots_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewSnapshotsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleSnapshotsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSnapshotRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSnapshotsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetSnapshotRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSnapshotsClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicySnapshotRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSnapshotsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListSnapshotsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSnapshotsClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicySnapshotRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSnapshotsClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsSnapshotRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSnapshotsClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewSnapshotsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsSnapshotRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/ssl_certificates_client.go b/compute/apiv1/ssl_certificates_client.go
new file mode 100644
index 0000000..509741e
--- /dev/null
+++ b/compute/apiv1/ssl_certificates_client.go
@@ -0,0 +1,452 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newSslCertificatesClientHook clientHook
+
+// SslCertificatesCallOptions contains the retry settings for each method of SslCertificatesClient.
+type SslCertificatesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalSslCertificatesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalSslCertificatesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListSslCertificatesRequest, ...gax.CallOption) (*computepb.SslCertificateAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteSslCertificateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetSslCertificateRequest, ...gax.CallOption) (*computepb.SslCertificate, error)
+	Insert(context.Context, *computepb.InsertSslCertificateRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListSslCertificatesRequest, ...gax.CallOption) (*computepb.SslCertificateList, error)
+}
+
+// SslCertificatesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The SslCertificates API.
+type SslCertificatesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalSslCertificatesClient
+
+	// The call options for this service.
+	CallOptions *SslCertificatesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *SslCertificatesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *SslCertificatesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *SslCertificatesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves the list of all SslCertificate resources, regional and global, available to the specified project.
+func (c *SslCertificatesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListSslCertificatesRequest, opts ...gax.CallOption) (*computepb.SslCertificateAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified SslCertificate resource.
+func (c *SslCertificatesClient) Delete(ctx context.Context, req *computepb.DeleteSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified SslCertificate resource. Gets a list of available SSL certificates by making a list() request.
+func (c *SslCertificatesClient) Get(ctx context.Context, req *computepb.GetSslCertificateRequest, opts ...gax.CallOption) (*computepb.SslCertificate, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a SslCertificate resource in the specified project using the data included in the request.
+func (c *SslCertificatesClient) Insert(ctx context.Context, req *computepb.InsertSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of SslCertificate resources available to the specified project.
+func (c *SslCertificatesClient) List(ctx context.Context, req *computepb.ListSslCertificatesRequest, opts ...gax.CallOption) (*computepb.SslCertificateList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type sslCertificatesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewSslCertificatesRESTClient creates a new ssl certificates rest client.
+//
+// The SslCertificates API.
+func NewSslCertificatesRESTClient(ctx context.Context, opts ...option.ClientOption) (*SslCertificatesClient, error) {
+	clientOpts := append(defaultSslCertificatesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &sslCertificatesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &SslCertificatesClient{internalClient: c, CallOptions: &SslCertificatesCallOptions{}}, nil
+}
+
+func defaultSslCertificatesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *sslCertificatesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *sslCertificatesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *sslCertificatesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves the list of all SslCertificate resources, regional and global, available to the specified project.
+func (c *sslCertificatesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListSslCertificatesRequest, opts ...gax.CallOption) (*computepb.SslCertificateAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/sslCertificates", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslCertificateAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified SslCertificate resource.
+func (c *sslCertificatesRESTClient) Delete(ctx context.Context, req *computepb.DeleteSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslCertificates/%v", req.GetProject(), req.GetSslCertificate())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified SslCertificate resource. Gets a list of available SSL certificates by making a list() request.
+func (c *sslCertificatesRESTClient) Get(ctx context.Context, req *computepb.GetSslCertificateRequest, opts ...gax.CallOption) (*computepb.SslCertificate, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslCertificates/%v", req.GetProject(), req.GetSslCertificate())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslCertificate{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a SslCertificate resource in the specified project using the data included in the request.
+func (c *sslCertificatesRESTClient) Insert(ctx context.Context, req *computepb.InsertSslCertificateRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSslCertificateResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslCertificates", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of SslCertificate resources available to the specified project.
+func (c *sslCertificatesRESTClient) List(ctx context.Context, req *computepb.ListSslCertificatesRequest, opts ...gax.CallOption) (*computepb.SslCertificateList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslCertificates", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslCertificateList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/ssl_certificates_client_example_test.go b/compute/apiv1/ssl_certificates_client_example_test.go
new file mode 100644
index 0000000..2859305
--- /dev/null
+++ b/compute/apiv1/ssl_certificates_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewSslCertificatesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleSslCertificatesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListSslCertificatesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslCertificatesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSslCertificateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslCertificatesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetSslCertificateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslCertificatesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertSslCertificateRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslCertificatesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewSslCertificatesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListSslCertificatesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/ssl_policies_client.go b/compute/apiv1/ssl_policies_client.go
new file mode 100644
index 0000000..b3ead7c
--- /dev/null
+++ b/compute/apiv1/ssl_policies_client.go
@@ -0,0 +1,507 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newSslPoliciesClientHook clientHook
+
+// SslPoliciesCallOptions contains the retry settings for each method of SslPoliciesClient.
+type SslPoliciesCallOptions struct {
+	Delete                []gax.CallOption
+	Get                   []gax.CallOption
+	Insert                []gax.CallOption
+	List                  []gax.CallOption
+	ListAvailableFeatures []gax.CallOption
+	Patch                 []gax.CallOption
+}
+
+// internalSslPoliciesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalSslPoliciesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteSslPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetSslPolicyRequest, ...gax.CallOption) (*computepb.SslPolicy, error)
+	Insert(context.Context, *computepb.InsertSslPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListSslPoliciesRequest, ...gax.CallOption) (*computepb.SslPoliciesList, error)
+	ListAvailableFeatures(context.Context, *computepb.ListAvailableFeaturesSslPoliciesRequest, ...gax.CallOption) (*computepb.SslPoliciesListAvailableFeaturesResponse, error)
+	Patch(context.Context, *computepb.PatchSslPolicyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// SslPoliciesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The SslPolicies API.
+type SslPoliciesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalSslPoliciesClient
+
+	// The call options for this service.
+	CallOptions *SslPoliciesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *SslPoliciesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *SslPoliciesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *SslPoliciesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified SSL policy. The SSL policy resource can be deleted only if it is not in use by any TargetHttpsProxy or TargetSslProxy resources.
+func (c *SslPoliciesClient) Delete(ctx context.Context, req *computepb.DeleteSslPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get lists all of the ordered rules present in a single specified policy.
+func (c *SslPoliciesClient) Get(ctx context.Context, req *computepb.GetSslPolicyRequest, opts ...gax.CallOption) (*computepb.SslPolicy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert returns the specified SSL policy resource. Gets a list of available SSL policies by making a list() request.
+func (c *SslPoliciesClient) Insert(ctx context.Context, req *computepb.InsertSslPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists all the SSL policies that have been configured for the specified project.
+func (c *SslPoliciesClient) List(ctx context.Context, req *computepb.ListSslPoliciesRequest, opts ...gax.CallOption) (*computepb.SslPoliciesList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListAvailableFeatures lists all features that can be specified in the SSL policy when using custom profile.
+func (c *SslPoliciesClient) ListAvailableFeatures(ctx context.Context, req *computepb.ListAvailableFeaturesSslPoliciesRequest, opts ...gax.CallOption) (*computepb.SslPoliciesListAvailableFeaturesResponse, error) {
+	return c.internalClient.ListAvailableFeatures(ctx, req, opts...)
+}
+
+// Patch patches the specified SSL policy with the data included in the request.
+func (c *SslPoliciesClient) Patch(ctx context.Context, req *computepb.PatchSslPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type sslPoliciesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewSslPoliciesRESTClient creates a new ssl policies rest client.
+//
+// The SslPolicies API.
+func NewSslPoliciesRESTClient(ctx context.Context, opts ...option.ClientOption) (*SslPoliciesClient, error) {
+	clientOpts := append(defaultSslPoliciesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &sslPoliciesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &SslPoliciesClient{internalClient: c, CallOptions: &SslPoliciesCallOptions{}}, nil
+}
+
+func defaultSslPoliciesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *sslPoliciesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *sslPoliciesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *sslPoliciesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified SSL policy. The SSL policy resource can be deleted only if it is not in use by any TargetHttpsProxy or TargetSslProxy resources.
+func (c *sslPoliciesRESTClient) Delete(ctx context.Context, req *computepb.DeleteSslPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslPolicies/%v", req.GetProject(), req.GetSslPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get lists all of the ordered rules present in a single specified policy.
+func (c *sslPoliciesRESTClient) Get(ctx context.Context, req *computepb.GetSslPolicyRequest, opts ...gax.CallOption) (*computepb.SslPolicy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslPolicies/%v", req.GetProject(), req.GetSslPolicy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslPolicy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert returns the specified SSL policy resource. Gets a list of available SSL policies by making a list() request.
+func (c *sslPoliciesRESTClient) Insert(ctx context.Context, req *computepb.InsertSslPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSslPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslPolicies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists all the SSL policies that have been configured for the specified project.
+func (c *sslPoliciesRESTClient) List(ctx context.Context, req *computepb.ListSslPoliciesRequest, opts ...gax.CallOption) (*computepb.SslPoliciesList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslPolicies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslPoliciesList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListAvailableFeatures lists all features that can be specified in the SSL policy when using custom profile.
+func (c *sslPoliciesRESTClient) ListAvailableFeatures(ctx context.Context, req *computepb.ListAvailableFeaturesSslPoliciesRequest, opts ...gax.CallOption) (*computepb.SslPoliciesListAvailableFeaturesResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslPolicies/listAvailableFeatures", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SslPoliciesListAvailableFeaturesResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified SSL policy with the data included in the request.
+func (c *sslPoliciesRESTClient) Patch(ctx context.Context, req *computepb.PatchSslPolicyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSslPolicyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/sslPolicies/%v", req.GetProject(), req.GetSslPolicy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/ssl_policies_client_example_test.go b/compute/apiv1/ssl_policies_client_example_test.go
new file mode 100644
index 0000000..a74e283
--- /dev/null
+++ b/compute/apiv1/ssl_policies_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewSslPoliciesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleSslPoliciesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSslPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslPoliciesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetSslPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslPoliciesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertSslPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslPoliciesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListSslPoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslPoliciesClient_ListAvailableFeatures() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListAvailableFeaturesSslPoliciesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListAvailableFeatures(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSslPoliciesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewSslPoliciesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchSslPolicyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/subnetworks_client.go b/compute/apiv1/subnetworks_client.go
new file mode 100644
index 0000000..d0bcf69
--- /dev/null
+++ b/compute/apiv1/subnetworks_client.go
@@ -0,0 +1,857 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newSubnetworksClientHook clientHook
+
+// SubnetworksCallOptions contains the retry settings for each method of SubnetworksClient.
+type SubnetworksCallOptions struct {
+	AggregatedList           []gax.CallOption
+	Delete                   []gax.CallOption
+	ExpandIpCidrRange        []gax.CallOption
+	Get                      []gax.CallOption
+	GetIamPolicy             []gax.CallOption
+	Insert                   []gax.CallOption
+	List                     []gax.CallOption
+	ListUsable               []gax.CallOption
+	Patch                    []gax.CallOption
+	SetIamPolicy             []gax.CallOption
+	SetPrivateIpGoogleAccess []gax.CallOption
+	TestIamPermissions       []gax.CallOption
+}
+
+// internalSubnetworksClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalSubnetworksClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListSubnetworksRequest, ...gax.CallOption) (*computepb.SubnetworkAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteSubnetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	ExpandIpCidrRange(context.Context, *computepb.ExpandIpCidrRangeSubnetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetSubnetworkRequest, ...gax.CallOption) (*computepb.Subnetwork, error)
+	GetIamPolicy(context.Context, *computepb.GetIamPolicySubnetworkRequest, ...gax.CallOption) (*computepb.Policy, error)
+	Insert(context.Context, *computepb.InsertSubnetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListSubnetworksRequest, ...gax.CallOption) (*computepb.SubnetworkList, error)
+	ListUsable(context.Context, *computepb.ListUsableSubnetworksRequest, ...gax.CallOption) (*computepb.UsableSubnetworksAggregatedList, error)
+	Patch(context.Context, *computepb.PatchSubnetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetIamPolicy(context.Context, *computepb.SetIamPolicySubnetworkRequest, ...gax.CallOption) (*computepb.Policy, error)
+	SetPrivateIpGoogleAccess(context.Context, *computepb.SetPrivateIpGoogleAccessSubnetworkRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsSubnetworkRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// SubnetworksClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Subnetworks API.
+type SubnetworksClient struct {
+	// The internal transport-dependent client.
+	internalClient internalSubnetworksClient
+
+	// The call options for this service.
+	CallOptions *SubnetworksCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *SubnetworksClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *SubnetworksClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *SubnetworksClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of subnetworks.
+func (c *SubnetworksClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListSubnetworksRequest, opts ...gax.CallOption) (*computepb.SubnetworkAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified subnetwork.
+func (c *SubnetworksClient) Delete(ctx context.Context, req *computepb.DeleteSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// ExpandIpCidrRange expands the IP CIDR range of the subnetwork to a specified value.
+func (c *SubnetworksClient) ExpandIpCidrRange(ctx context.Context, req *computepb.ExpandIpCidrRangeSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.ExpandIpCidrRange(ctx, req, opts...)
+}
+
+// Get returns the specified subnetwork. Gets a list of available subnetworks list() request.
+func (c *SubnetworksClient) Get(ctx context.Context, req *computepb.GetSubnetworkRequest, opts ...gax.CallOption) (*computepb.Subnetwork, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *SubnetworksClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicySubnetworkRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.GetIamPolicy(ctx, req, opts...)
+}
+
+// Insert creates a subnetwork in the specified project using the data included in the request.
+func (c *SubnetworksClient) Insert(ctx context.Context, req *computepb.InsertSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of subnetworks available to the specified project.
+func (c *SubnetworksClient) List(ctx context.Context, req *computepb.ListSubnetworksRequest, opts ...gax.CallOption) (*computepb.SubnetworkList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// ListUsable retrieves an aggregated list of all usable subnetworks in the project.
+func (c *SubnetworksClient) ListUsable(ctx context.Context, req *computepb.ListUsableSubnetworksRequest, opts ...gax.CallOption) (*computepb.UsableSubnetworksAggregatedList, error) {
+	return c.internalClient.ListUsable(ctx, req, opts...)
+}
+
+// Patch patches the specified subnetwork with the data included in the request. Only certain fields can be updated with a patch request as indicated in the field descriptions. You must specify the current fingerprint of the subnetwork resource being patched.
+func (c *SubnetworksClient) Patch(ctx context.Context, req *computepb.PatchSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *SubnetworksClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicySubnetworkRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	return c.internalClient.SetIamPolicy(ctx, req, opts...)
+}
+
+// SetPrivateIpGoogleAccess set whether VMs in this subnet can access Google services without assigning external IP addresses through Private Google Access.
+func (c *SubnetworksClient) SetPrivateIpGoogleAccess(ctx context.Context, req *computepb.SetPrivateIpGoogleAccessSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetPrivateIpGoogleAccess(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *SubnetworksClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsSubnetworkRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type subnetworksRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewSubnetworksRESTClient creates a new subnetworks rest client.
+//
+// The Subnetworks API.
+func NewSubnetworksRESTClient(ctx context.Context, opts ...option.ClientOption) (*SubnetworksClient, error) {
+	clientOpts := append(defaultSubnetworksRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &subnetworksRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &SubnetworksClient{internalClient: c, CallOptions: &SubnetworksCallOptions{}}, nil
+}
+
+func defaultSubnetworksRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *subnetworksRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *subnetworksRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *subnetworksRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of subnetworks.
+func (c *subnetworksRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListSubnetworksRequest, opts ...gax.CallOption) (*computepb.SubnetworkAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/subnetworks", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SubnetworkAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified subnetwork.
+func (c *subnetworksRESTClient) Delete(ctx context.Context, req *computepb.DeleteSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v", req.GetProject(), req.GetRegion(), req.GetSubnetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ExpandIpCidrRange expands the IP CIDR range of the subnetwork to a specified value.
+func (c *subnetworksRESTClient) ExpandIpCidrRange(ctx context.Context, req *computepb.ExpandIpCidrRangeSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSubnetworksExpandIpCidrRangeRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v/expandIpCidrRange", req.GetProject(), req.GetRegion(), req.GetSubnetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified subnetwork. Gets a list of available subnetworks list() request.
+func (c *subnetworksRESTClient) Get(ctx context.Context, req *computepb.GetSubnetworkRequest, opts ...gax.CallOption) (*computepb.Subnetwork, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v", req.GetProject(), req.GetRegion(), req.GetSubnetwork())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Subnetwork{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetIamPolicy gets the access control policy for a resource. May be empty if no such policy or resource exists.
+func (c *subnetworksRESTClient) GetIamPolicy(ctx context.Context, req *computepb.GetIamPolicySubnetworkRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v/getIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.OptionsRequestedPolicyVersion != nil {
+		params.Add("optionsRequestedPolicyVersion", fmt.Sprintf("%v", req.GetOptionsRequestedPolicyVersion()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a subnetwork in the specified project using the data included in the request.
+func (c *subnetworksRESTClient) Insert(ctx context.Context, req *computepb.InsertSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSubnetworkResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of subnetworks available to the specified project.
+func (c *subnetworksRESTClient) List(ctx context.Context, req *computepb.ListSubnetworksRequest, opts ...gax.CallOption) (*computepb.SubnetworkList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.SubnetworkList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// ListUsable retrieves an aggregated list of all usable subnetworks in the project.
+func (c *subnetworksRESTClient) ListUsable(ctx context.Context, req *computepb.ListUsableSubnetworksRequest, opts ...gax.CallOption) (*computepb.UsableSubnetworksAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/subnetworks/listUsable", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UsableSubnetworksAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified subnetwork with the data included in the request. Only certain fields can be updated with a patch request as indicated in the field descriptions. You must specify the current fingerprint of the subnetwork resource being patched.
+func (c *subnetworksRESTClient) Patch(ctx context.Context, req *computepb.PatchSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSubnetworkResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v", req.GetProject(), req.GetRegion(), req.GetSubnetwork())
+
+	params := url.Values{}
+	if req != nil && req.DrainTimeoutSeconds != nil {
+		params.Add("drainTimeoutSeconds", fmt.Sprintf("%v", req.GetDrainTimeoutSeconds()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetIamPolicy sets the access control policy on the specified resource. Replaces any existing policy.
+func (c *subnetworksRESTClient) SetIamPolicy(ctx context.Context, req *computepb.SetIamPolicySubnetworkRequest, opts ...gax.CallOption) (*computepb.Policy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetPolicyRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v/setIamPolicy", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Policy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetPrivateIpGoogleAccess set whether VMs in this subnet can access Google services without assigning external IP addresses through Private Google Access.
+func (c *subnetworksRESTClient) SetPrivateIpGoogleAccess(ctx context.Context, req *computepb.SetPrivateIpGoogleAccessSubnetworkRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSubnetworksSetPrivateIpGoogleAccessRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v/setPrivateIpGoogleAccess", req.GetProject(), req.GetRegion(), req.GetSubnetwork())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *subnetworksRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsSubnetworkRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/subnetworks/%v/testIamPermissions", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/subnetworks_client_example_test.go b/compute/apiv1/subnetworks_client_example_test.go
new file mode 100644
index 0000000..c561c83
--- /dev/null
+++ b/compute/apiv1/subnetworks_client_example_test.go
@@ -0,0 +1,264 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewSubnetworksRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleSubnetworksClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListSubnetworksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_ExpandIpCidrRange() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ExpandIpCidrRangeSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ExpandIpCidrRange(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_GetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetIamPolicySubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListSubnetworksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_ListUsable() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListUsableSubnetworksRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.ListUsable(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_SetIamPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetIamPolicySubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetIamPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_SetPrivateIpGoogleAccess() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetPrivateIpGoogleAccessSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetPrivateIpGoogleAccess(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleSubnetworksClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewSubnetworksRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsSubnetworkRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_grpc_proxies_client.go b/compute/apiv1/target_grpc_proxies_client.go
new file mode 100644
index 0000000..da17c2d
--- /dev/null
+++ b/compute/apiv1/target_grpc_proxies_client.go
@@ -0,0 +1,438 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetGrpcProxiesClientHook clientHook
+
+// TargetGrpcProxiesCallOptions contains the retry settings for each method of TargetGrpcProxiesClient.
+type TargetGrpcProxiesCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	Insert []gax.CallOption
+	List   []gax.CallOption
+	Patch  []gax.CallOption
+}
+
+// internalTargetGrpcProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetGrpcProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteTargetGrpcProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetGrpcProxyRequest, ...gax.CallOption) (*computepb.TargetGrpcProxy, error)
+	Insert(context.Context, *computepb.InsertTargetGrpcProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetGrpcProxiesRequest, ...gax.CallOption) (*computepb.TargetGrpcProxyList, error)
+	Patch(context.Context, *computepb.PatchTargetGrpcProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// TargetGrpcProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetGrpcProxies API.
+type TargetGrpcProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetGrpcProxiesClient
+
+	// The call options for this service.
+	CallOptions *TargetGrpcProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetGrpcProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetGrpcProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetGrpcProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified TargetGrpcProxy in the given scope
+func (c *TargetGrpcProxiesClient) Delete(ctx context.Context, req *computepb.DeleteTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetGrpcProxy resource in the given scope.
+func (c *TargetGrpcProxiesClient) Get(ctx context.Context, req *computepb.GetTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.TargetGrpcProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetGrpcProxy in the specified project in the given scope using the parameters that are included in the request.
+func (c *TargetGrpcProxiesClient) Insert(ctx context.Context, req *computepb.InsertTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List lists the TargetGrpcProxies for a project in the given scope.
+func (c *TargetGrpcProxiesClient) List(ctx context.Context, req *computepb.ListTargetGrpcProxiesRequest, opts ...gax.CallOption) (*computepb.TargetGrpcProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified TargetGrpcProxy resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *TargetGrpcProxiesClient) Patch(ctx context.Context, req *computepb.PatchTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetGrpcProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetGrpcProxiesRESTClient creates a new target grpc proxies rest client.
+//
+// The TargetGrpcProxies API.
+func NewTargetGrpcProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetGrpcProxiesClient, error) {
+	clientOpts := append(defaultTargetGrpcProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetGrpcProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetGrpcProxiesClient{internalClient: c, CallOptions: &TargetGrpcProxiesCallOptions{}}, nil
+}
+
+func defaultTargetGrpcProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetGrpcProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetGrpcProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetGrpcProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified TargetGrpcProxy in the given scope
+func (c *targetGrpcProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetGrpcProxies/%v", req.GetProject(), req.GetTargetGrpcProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetGrpcProxy resource in the given scope.
+func (c *targetGrpcProxiesRESTClient) Get(ctx context.Context, req *computepb.GetTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.TargetGrpcProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetGrpcProxies/%v", req.GetProject(), req.GetTargetGrpcProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetGrpcProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetGrpcProxy in the specified project in the given scope using the parameters that are included in the request.
+func (c *targetGrpcProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetGrpcProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetGrpcProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List lists the TargetGrpcProxies for a project in the given scope.
+func (c *targetGrpcProxiesRESTClient) List(ctx context.Context, req *computepb.ListTargetGrpcProxiesRequest, opts ...gax.CallOption) (*computepb.TargetGrpcProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetGrpcProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetGrpcProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified TargetGrpcProxy resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules.
+func (c *targetGrpcProxiesRESTClient) Patch(ctx context.Context, req *computepb.PatchTargetGrpcProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetGrpcProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetGrpcProxies/%v", req.GetProject(), req.GetTargetGrpcProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_grpc_proxies_client_example_test.go b/compute/apiv1/target_grpc_proxies_client_example_test.go
new file mode 100644
index 0000000..b1fdef1
--- /dev/null
+++ b/compute/apiv1/target_grpc_proxies_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetGrpcProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetGrpcProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetGrpcProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetGrpcProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetGrpcProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetGrpcProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetGrpcProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetGrpcProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetGrpcProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetGrpcProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetGrpcProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetGrpcProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetGrpcProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetGrpcProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetGrpcProxiesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewTargetGrpcProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchTargetGrpcProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_http_proxies_client.go b/compute/apiv1/target_http_proxies_client.go
new file mode 100644
index 0000000..a7dea19
--- /dev/null
+++ b/compute/apiv1/target_http_proxies_client.go
@@ -0,0 +1,568 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetHttpProxiesClientHook clientHook
+
+// TargetHttpProxiesCallOptions contains the retry settings for each method of TargetHttpProxiesClient.
+type TargetHttpProxiesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+	Patch          []gax.CallOption
+	SetUrlMap      []gax.CallOption
+}
+
+// internalTargetHttpProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetHttpProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListTargetHttpProxiesRequest, ...gax.CallOption) (*computepb.TargetHttpProxyAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetHttpProxyRequest, ...gax.CallOption) (*computepb.TargetHttpProxy, error)
+	Insert(context.Context, *computepb.InsertTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetHttpProxiesRequest, ...gax.CallOption) (*computepb.TargetHttpProxyList, error)
+	Patch(context.Context, *computepb.PatchTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetUrlMap(context.Context, *computepb.SetUrlMapTargetHttpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// TargetHttpProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetHttpProxies API.
+type TargetHttpProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetHttpProxiesClient
+
+	// The call options for this service.
+	CallOptions *TargetHttpProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetHttpProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetHttpProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetHttpProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves the list of all TargetHttpProxy resources, regional and global, available to the specified project.
+func (c *TargetHttpProxiesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetHttpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxyAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified TargetHttpProxy resource.
+func (c *TargetHttpProxiesClient) Delete(ctx context.Context, req *computepb.DeleteTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetHttpProxy resource. Gets a list of available target HTTP proxies by making a list() request.
+func (c *TargetHttpProxiesClient) Get(ctx context.Context, req *computepb.GetTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetHttpProxy resource in the specified project using the data included in the request.
+func (c *TargetHttpProxiesClient) Insert(ctx context.Context, req *computepb.InsertTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of TargetHttpProxy resources available to the specified project.
+func (c *TargetHttpProxiesClient) List(ctx context.Context, req *computepb.ListTargetHttpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified TargetHttpProxy resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)
+func (c *TargetHttpProxiesClient) Patch(ctx context.Context, req *computepb.PatchTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetUrlMap changes the URL map for TargetHttpProxy.
+func (c *TargetHttpProxiesClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetUrlMap(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetHttpProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetHttpProxiesRESTClient creates a new target http proxies rest client.
+//
+// The TargetHttpProxies API.
+func NewTargetHttpProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetHttpProxiesClient, error) {
+	clientOpts := append(defaultTargetHttpProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetHttpProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetHttpProxiesClient{internalClient: c, CallOptions: &TargetHttpProxiesCallOptions{}}, nil
+}
+
+func defaultTargetHttpProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetHttpProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetHttpProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetHttpProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves the list of all TargetHttpProxy resources, regional and global, available to the specified project.
+func (c *targetHttpProxiesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetHttpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxyAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/targetHttpProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpProxyAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified TargetHttpProxy resource.
+func (c *targetHttpProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpProxies/%v", req.GetProject(), req.GetTargetHttpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetHttpProxy resource. Gets a list of available target HTTP proxies by making a list() request.
+func (c *targetHttpProxiesRESTClient) Get(ctx context.Context, req *computepb.GetTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpProxies/%v", req.GetProject(), req.GetTargetHttpProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetHttpProxy resource in the specified project using the data included in the request.
+func (c *targetHttpProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of TargetHttpProxy resources available to the specified project.
+func (c *targetHttpProxiesRESTClient) List(ctx context.Context, req *computepb.ListTargetHttpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified TargetHttpProxy resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)
+func (c *targetHttpProxiesRESTClient) Patch(ctx context.Context, req *computepb.PatchTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpProxies/%v", req.GetProject(), req.GetTargetHttpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetUrlMap changes the URL map for TargetHttpProxy.
+func (c *targetHttpProxiesRESTClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapTargetHttpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/targetHttpProxies/%v/setUrlMap", req.GetProject(), req.GetTargetHttpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_http_proxies_client_example_test.go b/compute/apiv1/target_http_proxies_client_example_test.go
new file mode 100644
index 0000000..07d31ff
--- /dev/null
+++ b/compute/apiv1/target_http_proxies_client_example_test.go
@@ -0,0 +1,169 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetHttpProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetHttpProxiesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListTargetHttpProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetHttpProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpProxiesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpProxiesClient_SetUrlMap() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetUrlMapTargetHttpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetUrlMap(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_https_proxies_client.go b/compute/apiv1/target_https_proxies_client.go
new file mode 100644
index 0000000..c2af268
--- /dev/null
+++ b/compute/apiv1/target_https_proxies_client.go
@@ -0,0 +1,742 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetHttpsProxiesClientHook clientHook
+
+// TargetHttpsProxiesCallOptions contains the retry settings for each method of TargetHttpsProxiesClient.
+type TargetHttpsProxiesCallOptions struct {
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	Patch              []gax.CallOption
+	SetQuicOverride    []gax.CallOption
+	SetSslCertificates []gax.CallOption
+	SetSslPolicy       []gax.CallOption
+	SetUrlMap          []gax.CallOption
+}
+
+// internalTargetHttpsProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetHttpsProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListTargetHttpsProxiesRequest, ...gax.CallOption) (*computepb.TargetHttpsProxyAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.TargetHttpsProxy, error)
+	Insert(context.Context, *computepb.InsertTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetHttpsProxiesRequest, ...gax.CallOption) (*computepb.TargetHttpsProxyList, error)
+	Patch(context.Context, *computepb.PatchTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetQuicOverride(context.Context, *computepb.SetQuicOverrideTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetSslCertificates(context.Context, *computepb.SetSslCertificatesTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetSslPolicy(context.Context, *computepb.SetSslPolicyTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetUrlMap(context.Context, *computepb.SetUrlMapTargetHttpsProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// TargetHttpsProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetHttpsProxies API.
+type TargetHttpsProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetHttpsProxiesClient
+
+	// The call options for this service.
+	CallOptions *TargetHttpsProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetHttpsProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetHttpsProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetHttpsProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves the list of all TargetHttpsProxy resources, regional and global, available to the specified project.
+func (c *TargetHttpsProxiesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetHttpsProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxyAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified TargetHttpsProxy resource.
+func (c *TargetHttpsProxiesClient) Delete(ctx context.Context, req *computepb.DeleteTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetHttpsProxy resource. Gets a list of available target HTTPS proxies by making a list() request.
+func (c *TargetHttpsProxiesClient) Get(ctx context.Context, req *computepb.GetTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetHttpsProxy resource in the specified project using the data included in the request.
+func (c *TargetHttpsProxiesClient) Insert(ctx context.Context, req *computepb.InsertTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of TargetHttpsProxy resources available to the specified project.
+func (c *TargetHttpsProxiesClient) List(ctx context.Context, req *computepb.ListTargetHttpsProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified TargetHttpsProxy resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)
+func (c *TargetHttpsProxiesClient) Patch(ctx context.Context, req *computepb.PatchTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// SetQuicOverride sets the QUIC override policy for TargetHttpsProxy.
+func (c *TargetHttpsProxiesClient) SetQuicOverride(ctx context.Context, req *computepb.SetQuicOverrideTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetQuicOverride(ctx, req, opts...)
+}
+
+// SetSslCertificates replaces SslCertificates for TargetHttpsProxy.
+func (c *TargetHttpsProxiesClient) SetSslCertificates(ctx context.Context, req *computepb.SetSslCertificatesTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetSslCertificates(ctx, req, opts...)
+}
+
+// SetSslPolicy sets the SSL policy for TargetHttpsProxy. The SSL policy specifies the server-side support for SSL features. This affects connections between clients and the HTTPS proxy load balancer. They do not affect the connection between the load balancer and the backends.
+func (c *TargetHttpsProxiesClient) SetSslPolicy(ctx context.Context, req *computepb.SetSslPolicyTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetSslPolicy(ctx, req, opts...)
+}
+
+// SetUrlMap changes the URL map for TargetHttpsProxy.
+func (c *TargetHttpsProxiesClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetUrlMap(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetHttpsProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetHttpsProxiesRESTClient creates a new target https proxies rest client.
+//
+// The TargetHttpsProxies API.
+func NewTargetHttpsProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetHttpsProxiesClient, error) {
+	clientOpts := append(defaultTargetHttpsProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetHttpsProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetHttpsProxiesClient{internalClient: c, CallOptions: &TargetHttpsProxiesCallOptions{}}, nil
+}
+
+func defaultTargetHttpsProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetHttpsProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetHttpsProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetHttpsProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves the list of all TargetHttpsProxy resources, regional and global, available to the specified project.
+func (c *targetHttpsProxiesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetHttpsProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxyAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/targetHttpsProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpsProxyAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified TargetHttpsProxy resource.
+func (c *targetHttpsProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies/%v", req.GetProject(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetHttpsProxy resource. Gets a list of available target HTTPS proxies by making a list() request.
+func (c *targetHttpsProxiesRESTClient) Get(ctx context.Context, req *computepb.GetTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies/%v", req.GetProject(), req.GetTargetHttpsProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpsProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetHttpsProxy resource in the specified project using the data included in the request.
+func (c *targetHttpsProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpsProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of TargetHttpsProxy resources available to the specified project.
+func (c *targetHttpsProxiesRESTClient) List(ctx context.Context, req *computepb.ListTargetHttpsProxiesRequest, opts ...gax.CallOption) (*computepb.TargetHttpsProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetHttpsProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified TargetHttpsProxy resource with the data included in the request. This method supports PATCH semantics and uses JSON merge patch format and processing rules. (== suppress_warning http-rest-shadowed ==)
+func (c *targetHttpsProxiesRESTClient) Patch(ctx context.Context, req *computepb.PatchTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpsProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies/%v", req.GetProject(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetQuicOverride sets the QUIC override policy for TargetHttpsProxy.
+func (c *targetHttpsProxiesRESTClient) SetQuicOverride(ctx context.Context, req *computepb.SetQuicOverrideTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpsProxiesSetQuicOverrideRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies/%v/setQuicOverride", req.GetProject(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetSslCertificates replaces SslCertificates for TargetHttpsProxy.
+func (c *targetHttpsProxiesRESTClient) SetSslCertificates(ctx context.Context, req *computepb.SetSslCertificatesTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetHttpsProxiesSetSslCertificatesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/targetHttpsProxies/%v/setSslCertificates", req.GetProject(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetSslPolicy sets the SSL policy for TargetHttpsProxy. The SSL policy specifies the server-side support for SSL features. This affects connections between clients and the HTTPS proxy load balancer. They do not affect the connection between the load balancer and the backends.
+func (c *targetHttpsProxiesRESTClient) SetSslPolicy(ctx context.Context, req *computepb.SetSslPolicyTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSslPolicyReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetHttpsProxies/%v/setSslPolicy", req.GetProject(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetUrlMap changes the URL map for TargetHttpsProxy.
+func (c *targetHttpsProxiesRESTClient) SetUrlMap(ctx context.Context, req *computepb.SetUrlMapTargetHttpsProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/targetHttpsProxies/%v/setUrlMap", req.GetProject(), req.GetTargetHttpsProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_https_proxies_client_example_test.go b/compute/apiv1/target_https_proxies_client_example_test.go
new file mode 100644
index 0000000..3430ce2
--- /dev/null
+++ b/compute/apiv1/target_https_proxies_client_example_test.go
@@ -0,0 +1,226 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetHttpsProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetHttpsProxiesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListTargetHttpsProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetHttpsProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_SetQuicOverride() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetQuicOverrideTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetQuicOverride(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_SetSslCertificates() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSslCertificatesTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetSslCertificates(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_SetSslPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSslPolicyTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetSslPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetHttpsProxiesClient_SetUrlMap() {
+	ctx := context.Background()
+	c, err := compute.NewTargetHttpsProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetUrlMapTargetHttpsProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetUrlMap(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_instances_client.go b/compute/apiv1/target_instances_client.go
new file mode 100644
index 0000000..25b0514
--- /dev/null
+++ b/compute/apiv1/target_instances_client.go
@@ -0,0 +1,452 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetInstancesClientHook clientHook
+
+// TargetInstancesCallOptions contains the retry settings for each method of TargetInstancesClient.
+type TargetInstancesCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalTargetInstancesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetInstancesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListTargetInstancesRequest, ...gax.CallOption) (*computepb.TargetInstanceAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteTargetInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetInstanceRequest, ...gax.CallOption) (*computepb.TargetInstance, error)
+	Insert(context.Context, *computepb.InsertTargetInstanceRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetInstancesRequest, ...gax.CallOption) (*computepb.TargetInstanceList, error)
+}
+
+// TargetInstancesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetInstances API.
+type TargetInstancesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetInstancesClient
+
+	// The call options for this service.
+	CallOptions *TargetInstancesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetInstancesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetInstancesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetInstancesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of target instances.
+func (c *TargetInstancesClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetInstancesRequest, opts ...gax.CallOption) (*computepb.TargetInstanceAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified TargetInstance resource.
+func (c *TargetInstancesClient) Delete(ctx context.Context, req *computepb.DeleteTargetInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetInstance resource. Gets a list of available target instances by making a list() request.
+func (c *TargetInstancesClient) Get(ctx context.Context, req *computepb.GetTargetInstanceRequest, opts ...gax.CallOption) (*computepb.TargetInstance, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetInstance resource in the specified project and zone using the data included in the request.
+func (c *TargetInstancesClient) Insert(ctx context.Context, req *computepb.InsertTargetInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of TargetInstance resources available to the specified project and zone.
+func (c *TargetInstancesClient) List(ctx context.Context, req *computepb.ListTargetInstancesRequest, opts ...gax.CallOption) (*computepb.TargetInstanceList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetInstancesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetInstancesRESTClient creates a new target instances rest client.
+//
+// The TargetInstances API.
+func NewTargetInstancesRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetInstancesClient, error) {
+	clientOpts := append(defaultTargetInstancesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetInstancesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetInstancesClient{internalClient: c, CallOptions: &TargetInstancesCallOptions{}}, nil
+}
+
+func defaultTargetInstancesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetInstancesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetInstancesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetInstancesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of target instances.
+func (c *targetInstancesRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetInstancesRequest, opts ...gax.CallOption) (*computepb.TargetInstanceAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/targetInstances", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetInstanceAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified TargetInstance resource.
+func (c *targetInstancesRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/targetInstances/%v", req.GetProject(), req.GetZone(), req.GetTargetInstance())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetInstance resource. Gets a list of available target instances by making a list() request.
+func (c *targetInstancesRESTClient) Get(ctx context.Context, req *computepb.GetTargetInstanceRequest, opts ...gax.CallOption) (*computepb.TargetInstance, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/targetInstances/%v", req.GetProject(), req.GetZone(), req.GetTargetInstance())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetInstance{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetInstance resource in the specified project and zone using the data included in the request.
+func (c *targetInstancesRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetInstanceRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetInstanceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/targetInstances", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of TargetInstance resources available to the specified project and zone.
+func (c *targetInstancesRESTClient) List(ctx context.Context, req *computepb.ListTargetInstancesRequest, opts ...gax.CallOption) (*computepb.TargetInstanceList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/targetInstances", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetInstanceList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_instances_client_example_test.go b/compute/apiv1/target_instances_client_example_test.go
new file mode 100644
index 0000000..de3679b
--- /dev/null
+++ b/compute/apiv1/target_instances_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetInstancesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetInstancesClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewTargetInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListTargetInstancesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetInstancesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetInstancesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetInstancesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetInstanceRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetInstancesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetInstancesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetInstancesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_pools_client.go b/compute/apiv1/target_pools_client.go
new file mode 100644
index 0000000..f05abec
--- /dev/null
+++ b/compute/apiv1/target_pools_client.go
@@ -0,0 +1,796 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetPoolsClientHook clientHook
+
+// TargetPoolsCallOptions contains the retry settings for each method of TargetPoolsClient.
+type TargetPoolsCallOptions struct {
+	AddHealthCheck    []gax.CallOption
+	AddInstance       []gax.CallOption
+	AggregatedList    []gax.CallOption
+	Delete            []gax.CallOption
+	Get               []gax.CallOption
+	GetHealth         []gax.CallOption
+	Insert            []gax.CallOption
+	List              []gax.CallOption
+	RemoveHealthCheck []gax.CallOption
+	RemoveInstance    []gax.CallOption
+	SetBackup         []gax.CallOption
+}
+
+// internalTargetPoolsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetPoolsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AddHealthCheck(context.Context, *computepb.AddHealthCheckTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AddInstance(context.Context, *computepb.AddInstanceTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+	AggregatedList(context.Context, *computepb.AggregatedListTargetPoolsRequest, ...gax.CallOption) (*computepb.TargetPoolAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetPoolRequest, ...gax.CallOption) (*computepb.TargetPool, error)
+	GetHealth(context.Context, *computepb.GetHealthTargetPoolRequest, ...gax.CallOption) (*computepb.TargetPoolInstanceHealth, error)
+	Insert(context.Context, *computepb.InsertTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetPoolsRequest, ...gax.CallOption) (*computepb.TargetPoolList, error)
+	RemoveHealthCheck(context.Context, *computepb.RemoveHealthCheckTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+	RemoveInstance(context.Context, *computepb.RemoveInstanceTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetBackup(context.Context, *computepb.SetBackupTargetPoolRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// TargetPoolsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetPools API.
+type TargetPoolsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetPoolsClient
+
+	// The call options for this service.
+	CallOptions *TargetPoolsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetPoolsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetPoolsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetPoolsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AddHealthCheck adds health check URLs to a target pool.
+func (c *TargetPoolsClient) AddHealthCheck(ctx context.Context, req *computepb.AddHealthCheckTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddHealthCheck(ctx, req, opts...)
+}
+
+// AddInstance adds an instance to a target pool.
+func (c *TargetPoolsClient) AddInstance(ctx context.Context, req *computepb.AddInstanceTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.AddInstance(ctx, req, opts...)
+}
+
+// AggregatedList retrieves an aggregated list of target pools.
+func (c *TargetPoolsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetPoolsRequest, opts ...gax.CallOption) (*computepb.TargetPoolAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified target pool.
+func (c *TargetPoolsClient) Delete(ctx context.Context, req *computepb.DeleteTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified target pool. Gets a list of available target pools by making a list() request.
+func (c *TargetPoolsClient) Get(ctx context.Context, req *computepb.GetTargetPoolRequest, opts ...gax.CallOption) (*computepb.TargetPool, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetHealth gets the most recent health check results for each IP for the instance that is referenced by the given target pool.
+func (c *TargetPoolsClient) GetHealth(ctx context.Context, req *computepb.GetHealthTargetPoolRequest, opts ...gax.CallOption) (*computepb.TargetPoolInstanceHealth, error) {
+	return c.internalClient.GetHealth(ctx, req, opts...)
+}
+
+// Insert creates a target pool in the specified project and region using the data included in the request.
+func (c *TargetPoolsClient) Insert(ctx context.Context, req *computepb.InsertTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of target pools available to the specified project and region.
+func (c *TargetPoolsClient) List(ctx context.Context, req *computepb.ListTargetPoolsRequest, opts ...gax.CallOption) (*computepb.TargetPoolList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// RemoveHealthCheck removes health check URL from a target pool.
+func (c *TargetPoolsClient) RemoveHealthCheck(ctx context.Context, req *computepb.RemoveHealthCheckTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveHealthCheck(ctx, req, opts...)
+}
+
+// RemoveInstance removes instance URL from a target pool.
+func (c *TargetPoolsClient) RemoveInstance(ctx context.Context, req *computepb.RemoveInstanceTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.RemoveInstance(ctx, req, opts...)
+}
+
+// SetBackup changes a backup target pool’s configurations.
+func (c *TargetPoolsClient) SetBackup(ctx context.Context, req *computepb.SetBackupTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetBackup(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetPoolsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetPoolsRESTClient creates a new target pools rest client.
+//
+// The TargetPools API.
+func NewTargetPoolsRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetPoolsClient, error) {
+	clientOpts := append(defaultTargetPoolsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetPoolsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetPoolsClient{internalClient: c, CallOptions: &TargetPoolsCallOptions{}}, nil
+}
+
+func defaultTargetPoolsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetPoolsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetPoolsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetPoolsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AddHealthCheck adds health check URLs to a target pool.
+func (c *targetPoolsRESTClient) AddHealthCheck(ctx context.Context, req *computepb.AddHealthCheckTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetPoolsAddHealthCheckRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v/addHealthCheck", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AddInstance adds an instance to a target pool.
+func (c *targetPoolsRESTClient) AddInstance(ctx context.Context, req *computepb.AddInstanceTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetPoolsAddInstanceRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v/addInstance", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// AggregatedList retrieves an aggregated list of target pools.
+func (c *targetPoolsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetPoolsRequest, opts ...gax.CallOption) (*computepb.TargetPoolAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/targetPools", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetPoolAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified target pool.
+func (c *targetPoolsRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified target pool. Gets a list of available target pools by making a list() request.
+func (c *targetPoolsRESTClient) Get(ctx context.Context, req *computepb.GetTargetPoolRequest, opts ...gax.CallOption) (*computepb.TargetPool, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetPool{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetHealth gets the most recent health check results for each IP for the instance that is referenced by the given target pool.
+func (c *targetPoolsRESTClient) GetHealth(ctx context.Context, req *computepb.GetHealthTargetPoolRequest, opts ...gax.CallOption) (*computepb.TargetPoolInstanceHealth, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetInstanceReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v/getHealth", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetPoolInstanceHealth{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a target pool in the specified project and region using the data included in the request.
+func (c *targetPoolsRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetPoolResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of target pools available to the specified project and region.
+func (c *targetPoolsRESTClient) List(ctx context.Context, req *computepb.ListTargetPoolsRequest, opts ...gax.CallOption) (*computepb.TargetPoolList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetPoolList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveHealthCheck removes health check URL from a target pool.
+func (c *targetPoolsRESTClient) RemoveHealthCheck(ctx context.Context, req *computepb.RemoveHealthCheckTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetPoolsRemoveHealthCheckRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v/removeHealthCheck", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// RemoveInstance removes instance URL from a target pool.
+func (c *targetPoolsRESTClient) RemoveInstance(ctx context.Context, req *computepb.RemoveInstanceTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetPoolsRemoveInstanceRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v/removeInstance", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetBackup changes a backup target pool’s configurations.
+func (c *targetPoolsRESTClient) SetBackup(ctx context.Context, req *computepb.SetBackupTargetPoolRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetPools/%v/setBackup", req.GetProject(), req.GetRegion(), req.GetTargetPool())
+
+	params := url.Values{}
+	if req != nil && req.FailoverRatio != nil {
+		params.Add("failoverRatio", fmt.Sprintf("%v", req.GetFailoverRatio()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_pools_client_example_test.go b/compute/apiv1/target_pools_client_example_test.go
new file mode 100644
index 0000000..480016f
--- /dev/null
+++ b/compute/apiv1/target_pools_client_example_test.go
@@ -0,0 +1,245 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetPoolsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetPoolsClient_AddHealthCheck() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddHealthCheckTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddHealthCheck(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_AddInstance() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AddInstanceTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AddInstance(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListTargetPoolsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_GetHealth() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetHealthTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetHealth(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetPoolsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_RemoveHealthCheck() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveHealthCheckTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveHealthCheck(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_RemoveInstance() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.RemoveInstanceTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.RemoveInstance(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetPoolsClient_SetBackup() {
+	ctx := context.Background()
+	c, err := compute.NewTargetPoolsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetBackupTargetPoolRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetBackup(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_ssl_proxies_client.go b/compute/apiv1/target_ssl_proxies_client.go
new file mode 100644
index 0000000..bbbd9dc
--- /dev/null
+++ b/compute/apiv1/target_ssl_proxies_client.go
@@ -0,0 +1,612 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetSslProxiesClientHook clientHook
+
+// TargetSslProxiesCallOptions contains the retry settings for each method of TargetSslProxiesClient.
+type TargetSslProxiesCallOptions struct {
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetBackendService  []gax.CallOption
+	SetProxyHeader     []gax.CallOption
+	SetSslCertificates []gax.CallOption
+	SetSslPolicy       []gax.CallOption
+}
+
+// internalTargetSslProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetSslProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteTargetSslProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetSslProxyRequest, ...gax.CallOption) (*computepb.TargetSslProxy, error)
+	Insert(context.Context, *computepb.InsertTargetSslProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetSslProxiesRequest, ...gax.CallOption) (*computepb.TargetSslProxyList, error)
+	SetBackendService(context.Context, *computepb.SetBackendServiceTargetSslProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetProxyHeader(context.Context, *computepb.SetProxyHeaderTargetSslProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetSslCertificates(context.Context, *computepb.SetSslCertificatesTargetSslProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetSslPolicy(context.Context, *computepb.SetSslPolicyTargetSslProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// TargetSslProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetSslProxies API.
+type TargetSslProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetSslProxiesClient
+
+	// The call options for this service.
+	CallOptions *TargetSslProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetSslProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetSslProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetSslProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified TargetSslProxy resource.
+func (c *TargetSslProxiesClient) Delete(ctx context.Context, req *computepb.DeleteTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetSslProxy resource. Gets a list of available target SSL proxies by making a list() request.
+func (c *TargetSslProxiesClient) Get(ctx context.Context, req *computepb.GetTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.TargetSslProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetSslProxy resource in the specified project using the data included in the request.
+func (c *TargetSslProxiesClient) Insert(ctx context.Context, req *computepb.InsertTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of TargetSslProxy resources available to the specified project.
+func (c *TargetSslProxiesClient) List(ctx context.Context, req *computepb.ListTargetSslProxiesRequest, opts ...gax.CallOption) (*computepb.TargetSslProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetBackendService changes the BackendService for TargetSslProxy.
+func (c *TargetSslProxiesClient) SetBackendService(ctx context.Context, req *computepb.SetBackendServiceTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetBackendService(ctx, req, opts...)
+}
+
+// SetProxyHeader changes the ProxyHeaderType for TargetSslProxy.
+func (c *TargetSslProxiesClient) SetProxyHeader(ctx context.Context, req *computepb.SetProxyHeaderTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetProxyHeader(ctx, req, opts...)
+}
+
+// SetSslCertificates changes SslCertificates for TargetSslProxy.
+func (c *TargetSslProxiesClient) SetSslCertificates(ctx context.Context, req *computepb.SetSslCertificatesTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetSslCertificates(ctx, req, opts...)
+}
+
+// SetSslPolicy sets the SSL policy for TargetSslProxy. The SSL policy specifies the server-side support for SSL features. This affects connections between clients and the SSL proxy load balancer. They do not affect the connection between the load balancer and the backends.
+func (c *TargetSslProxiesClient) SetSslPolicy(ctx context.Context, req *computepb.SetSslPolicyTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetSslPolicy(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetSslProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetSslProxiesRESTClient creates a new target ssl proxies rest client.
+//
+// The TargetSslProxies API.
+func NewTargetSslProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetSslProxiesClient, error) {
+	clientOpts := append(defaultTargetSslProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetSslProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetSslProxiesClient{internalClient: c, CallOptions: &TargetSslProxiesCallOptions{}}, nil
+}
+
+func defaultTargetSslProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetSslProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetSslProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetSslProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified TargetSslProxy resource.
+func (c *targetSslProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies/%v", req.GetProject(), req.GetTargetSslProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetSslProxy resource. Gets a list of available target SSL proxies by making a list() request.
+func (c *targetSslProxiesRESTClient) Get(ctx context.Context, req *computepb.GetTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.TargetSslProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies/%v", req.GetProject(), req.GetTargetSslProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetSslProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetSslProxy resource in the specified project using the data included in the request.
+func (c *targetSslProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetSslProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of TargetSslProxy resources available to the specified project.
+func (c *targetSslProxiesRESTClient) List(ctx context.Context, req *computepb.ListTargetSslProxiesRequest, opts ...gax.CallOption) (*computepb.TargetSslProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetSslProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetBackendService changes the BackendService for TargetSslProxy.
+func (c *targetSslProxiesRESTClient) SetBackendService(ctx context.Context, req *computepb.SetBackendServiceTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetSslProxiesSetBackendServiceRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies/%v/setBackendService", req.GetProject(), req.GetTargetSslProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetProxyHeader changes the ProxyHeaderType for TargetSslProxy.
+func (c *targetSslProxiesRESTClient) SetProxyHeader(ctx context.Context, req *computepb.SetProxyHeaderTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetSslProxiesSetProxyHeaderRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies/%v/setProxyHeader", req.GetProject(), req.GetTargetSslProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetSslCertificates changes SslCertificates for TargetSslProxy.
+func (c *targetSslProxiesRESTClient) SetSslCertificates(ctx context.Context, req *computepb.SetSslCertificatesTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetSslProxiesSetSslCertificatesRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies/%v/setSslCertificates", req.GetProject(), req.GetTargetSslProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetSslPolicy sets the SSL policy for TargetSslProxy. The SSL policy specifies the server-side support for SSL features. This affects connections between clients and the SSL proxy load balancer. They do not affect the connection between the load balancer and the backends.
+func (c *targetSslProxiesRESTClient) SetSslPolicy(ctx context.Context, req *computepb.SetSslPolicyTargetSslProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetSslPolicyReferenceResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetSslProxies/%v/setSslPolicy", req.GetProject(), req.GetTargetSslProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_ssl_proxies_client_example_test.go b/compute/apiv1/target_ssl_proxies_client_example_test.go
new file mode 100644
index 0000000..09db740
--- /dev/null
+++ b/compute/apiv1/target_ssl_proxies_client_example_test.go
@@ -0,0 +1,188 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetSslProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetSslProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetSslProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_SetBackendService() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetBackendServiceTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetBackendService(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_SetProxyHeader() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetProxyHeaderTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetProxyHeader(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_SetSslCertificates() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSslCertificatesTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetSslCertificates(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetSslProxiesClient_SetSslPolicy() {
+	ctx := context.Background()
+	c, err := compute.NewTargetSslProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetSslPolicyTargetSslProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetSslPolicy(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_tcp_proxies_client.go b/compute/apiv1/target_tcp_proxies_client.go
new file mode 100644
index 0000000..f263121
--- /dev/null
+++ b/compute/apiv1/target_tcp_proxies_client.go
@@ -0,0 +1,496 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetTcpProxiesClientHook clientHook
+
+// TargetTcpProxiesCallOptions contains the retry settings for each method of TargetTcpProxiesClient.
+type TargetTcpProxiesCallOptions struct {
+	Delete            []gax.CallOption
+	Get               []gax.CallOption
+	Insert            []gax.CallOption
+	List              []gax.CallOption
+	SetBackendService []gax.CallOption
+	SetProxyHeader    []gax.CallOption
+}
+
+// internalTargetTcpProxiesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetTcpProxiesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteTargetTcpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetTcpProxyRequest, ...gax.CallOption) (*computepb.TargetTcpProxy, error)
+	Insert(context.Context, *computepb.InsertTargetTcpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetTcpProxiesRequest, ...gax.CallOption) (*computepb.TargetTcpProxyList, error)
+	SetBackendService(context.Context, *computepb.SetBackendServiceTargetTcpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+	SetProxyHeader(context.Context, *computepb.SetProxyHeaderTargetTcpProxyRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// TargetTcpProxiesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetTcpProxies API.
+type TargetTcpProxiesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetTcpProxiesClient
+
+	// The call options for this service.
+	CallOptions *TargetTcpProxiesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetTcpProxiesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetTcpProxiesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetTcpProxiesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified TargetTcpProxy resource.
+func (c *TargetTcpProxiesClient) Delete(ctx context.Context, req *computepb.DeleteTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified TargetTcpProxy resource. Gets a list of available target TCP proxies by making a list() request.
+func (c *TargetTcpProxiesClient) Get(ctx context.Context, req *computepb.GetTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.TargetTcpProxy, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a TargetTcpProxy resource in the specified project using the data included in the request.
+func (c *TargetTcpProxiesClient) Insert(ctx context.Context, req *computepb.InsertTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves the list of TargetTcpProxy resources available to the specified project.
+func (c *TargetTcpProxiesClient) List(ctx context.Context, req *computepb.ListTargetTcpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetTcpProxyList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetBackendService changes the BackendService for TargetTcpProxy.
+func (c *TargetTcpProxiesClient) SetBackendService(ctx context.Context, req *computepb.SetBackendServiceTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetBackendService(ctx, req, opts...)
+}
+
+// SetProxyHeader changes the ProxyHeaderType for TargetTcpProxy.
+func (c *TargetTcpProxiesClient) SetProxyHeader(ctx context.Context, req *computepb.SetProxyHeaderTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetProxyHeader(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetTcpProxiesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetTcpProxiesRESTClient creates a new target tcp proxies rest client.
+//
+// The TargetTcpProxies API.
+func NewTargetTcpProxiesRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetTcpProxiesClient, error) {
+	clientOpts := append(defaultTargetTcpProxiesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetTcpProxiesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetTcpProxiesClient{internalClient: c, CallOptions: &TargetTcpProxiesCallOptions{}}, nil
+}
+
+func defaultTargetTcpProxiesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetTcpProxiesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetTcpProxiesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetTcpProxiesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified TargetTcpProxy resource.
+func (c *targetTcpProxiesRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetTcpProxies/%v", req.GetProject(), req.GetTargetTcpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified TargetTcpProxy resource. Gets a list of available target TCP proxies by making a list() request.
+func (c *targetTcpProxiesRESTClient) Get(ctx context.Context, req *computepb.GetTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.TargetTcpProxy, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetTcpProxies/%v", req.GetProject(), req.GetTargetTcpProxy())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetTcpProxy{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a TargetTcpProxy resource in the specified project using the data included in the request.
+func (c *targetTcpProxiesRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetTcpProxyResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetTcpProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of TargetTcpProxy resources available to the specified project.
+func (c *targetTcpProxiesRESTClient) List(ctx context.Context, req *computepb.ListTargetTcpProxiesRequest, opts ...gax.CallOption) (*computepb.TargetTcpProxyList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetTcpProxies", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetTcpProxyList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetBackendService changes the BackendService for TargetTcpProxy.
+func (c *targetTcpProxiesRESTClient) SetBackendService(ctx context.Context, req *computepb.SetBackendServiceTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetTcpProxiesSetBackendServiceRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetTcpProxies/%v/setBackendService", req.GetProject(), req.GetTargetTcpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetProxyHeader changes the ProxyHeaderType for TargetTcpProxy.
+func (c *targetTcpProxiesRESTClient) SetProxyHeader(ctx context.Context, req *computepb.SetProxyHeaderTargetTcpProxyRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetTcpProxiesSetProxyHeaderRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/targetTcpProxies/%v/setProxyHeader", req.GetProject(), req.GetTargetTcpProxy())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_tcp_proxies_client_example_test.go b/compute/apiv1/target_tcp_proxies_client_example_test.go
new file mode 100644
index 0000000..0e95e1f
--- /dev/null
+++ b/compute/apiv1/target_tcp_proxies_client_example_test.go
@@ -0,0 +1,150 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetTcpProxiesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetTcpProxiesClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetTcpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetTcpProxiesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetTcpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetTcpProxiesClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetTcpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetTcpProxiesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetTcpProxiesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetTcpProxiesClient_SetBackendService() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetBackendServiceTargetTcpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetBackendService(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetTcpProxiesClient_SetProxyHeader() {
+	ctx := context.Background()
+	c, err := compute.NewTargetTcpProxiesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetProxyHeaderTargetTcpProxyRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetProxyHeader(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/target_vpn_gateways_client.go b/compute/apiv1/target_vpn_gateways_client.go
new file mode 100644
index 0000000..996e785
--- /dev/null
+++ b/compute/apiv1/target_vpn_gateways_client.go
@@ -0,0 +1,452 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newTargetVpnGatewaysClientHook clientHook
+
+// TargetVpnGatewaysCallOptions contains the retry settings for each method of TargetVpnGatewaysClient.
+type TargetVpnGatewaysCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalTargetVpnGatewaysClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalTargetVpnGatewaysClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListTargetVpnGatewaysRequest, ...gax.CallOption) (*computepb.TargetVpnGatewayAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteTargetVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetTargetVpnGatewayRequest, ...gax.CallOption) (*computepb.TargetVpnGateway, error)
+	Insert(context.Context, *computepb.InsertTargetVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListTargetVpnGatewaysRequest, ...gax.CallOption) (*computepb.TargetVpnGatewayList, error)
+}
+
+// TargetVpnGatewaysClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The TargetVpnGateways API.
+type TargetVpnGatewaysClient struct {
+	// The internal transport-dependent client.
+	internalClient internalTargetVpnGatewaysClient
+
+	// The call options for this service.
+	CallOptions *TargetVpnGatewaysCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *TargetVpnGatewaysClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *TargetVpnGatewaysClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *TargetVpnGatewaysClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of target VPN gateways.
+func (c *TargetVpnGatewaysClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.TargetVpnGatewayAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified target VPN gateway.
+func (c *TargetVpnGatewaysClient) Delete(ctx context.Context, req *computepb.DeleteTargetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified target VPN gateway. Gets a list of available target VPN gateways by making a list() request.
+func (c *TargetVpnGatewaysClient) Get(ctx context.Context, req *computepb.GetTargetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.TargetVpnGateway, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a target VPN gateway in the specified project and region using the data included in the request.
+func (c *TargetVpnGatewaysClient) Insert(ctx context.Context, req *computepb.InsertTargetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of target VPN gateways available to the specified project and region.
+func (c *TargetVpnGatewaysClient) List(ctx context.Context, req *computepb.ListTargetVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.TargetVpnGatewayList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type targetVpnGatewaysRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewTargetVpnGatewaysRESTClient creates a new target vpn gateways rest client.
+//
+// The TargetVpnGateways API.
+func NewTargetVpnGatewaysRESTClient(ctx context.Context, opts ...option.ClientOption) (*TargetVpnGatewaysClient, error) {
+	clientOpts := append(defaultTargetVpnGatewaysRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &targetVpnGatewaysRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &TargetVpnGatewaysClient{internalClient: c, CallOptions: &TargetVpnGatewaysCallOptions{}}, nil
+}
+
+func defaultTargetVpnGatewaysRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *targetVpnGatewaysRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *targetVpnGatewaysRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *targetVpnGatewaysRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of target VPN gateways.
+func (c *targetVpnGatewaysRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListTargetVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.TargetVpnGatewayAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/targetVpnGateways", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetVpnGatewayAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified target VPN gateway.
+func (c *targetVpnGatewaysRESTClient) Delete(ctx context.Context, req *computepb.DeleteTargetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetVpnGateways/%v", req.GetProject(), req.GetRegion(), req.GetTargetVpnGateway())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified target VPN gateway. Gets a list of available target VPN gateways by making a list() request.
+func (c *targetVpnGatewaysRESTClient) Get(ctx context.Context, req *computepb.GetTargetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.TargetVpnGateway, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetVpnGateways/%v", req.GetProject(), req.GetRegion(), req.GetTargetVpnGateway())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetVpnGateway{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a target VPN gateway in the specified project and region using the data included in the request.
+func (c *targetVpnGatewaysRESTClient) Insert(ctx context.Context, req *computepb.InsertTargetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTargetVpnGatewayResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetVpnGateways", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of target VPN gateways available to the specified project and region.
+func (c *targetVpnGatewaysRESTClient) List(ctx context.Context, req *computepb.ListTargetVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.TargetVpnGatewayList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/targetVpnGateways", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TargetVpnGatewayList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/target_vpn_gateways_client_example_test.go b/compute/apiv1/target_vpn_gateways_client_example_test.go
new file mode 100644
index 0000000..1c8e35c
--- /dev/null
+++ b/compute/apiv1/target_vpn_gateways_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewTargetVpnGatewaysRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewTargetVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleTargetVpnGatewaysClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewTargetVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListTargetVpnGatewaysRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetVpnGatewaysClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewTargetVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteTargetVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetVpnGatewaysClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewTargetVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetTargetVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetVpnGatewaysClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewTargetVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertTargetVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleTargetVpnGatewaysClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewTargetVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListTargetVpnGatewaysRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/url_maps_client.go b/compute/apiv1/url_maps_client.go
new file mode 100644
index 0000000..798e936
--- /dev/null
+++ b/compute/apiv1/url_maps_client.go
@@ -0,0 +1,687 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newUrlMapsClientHook clientHook
+
+// UrlMapsCallOptions contains the retry settings for each method of UrlMapsClient.
+type UrlMapsCallOptions struct {
+	AggregatedList  []gax.CallOption
+	Delete          []gax.CallOption
+	Get             []gax.CallOption
+	Insert          []gax.CallOption
+	InvalidateCache []gax.CallOption
+	List            []gax.CallOption
+	Patch           []gax.CallOption
+	Update          []gax.CallOption
+	Validate        []gax.CallOption
+}
+
+// internalUrlMapsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalUrlMapsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListUrlMapsRequest, ...gax.CallOption) (*computepb.UrlMapsAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetUrlMapRequest, ...gax.CallOption) (*computepb.UrlMap, error)
+	Insert(context.Context, *computepb.InsertUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	InvalidateCache(context.Context, *computepb.InvalidateCacheUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListUrlMapsRequest, ...gax.CallOption) (*computepb.UrlMapList, error)
+	Patch(context.Context, *computepb.PatchUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Update(context.Context, *computepb.UpdateUrlMapRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Validate(context.Context, *computepb.ValidateUrlMapRequest, ...gax.CallOption) (*computepb.UrlMapsValidateResponse, error)
+}
+
+// UrlMapsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The UrlMaps API.
+type UrlMapsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalUrlMapsClient
+
+	// The call options for this service.
+	CallOptions *UrlMapsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *UrlMapsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *UrlMapsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *UrlMapsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves the list of all UrlMap resources, regional and global, available to the specified project.
+func (c *UrlMapsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListUrlMapsRequest, opts ...gax.CallOption) (*computepb.UrlMapsAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified UrlMap resource.
+func (c *UrlMapsClient) Delete(ctx context.Context, req *computepb.DeleteUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified UrlMap resource. Gets a list of available URL maps by making a list() request.
+func (c *UrlMapsClient) Get(ctx context.Context, req *computepb.GetUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMap, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a UrlMap resource in the specified project using the data included in the request.
+func (c *UrlMapsClient) Insert(ctx context.Context, req *computepb.InsertUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// InvalidateCache initiates a cache invalidation operation, invalidating the specified path, scoped to the specified UrlMap.
+//
+// For more information, see Invalidating cached content (at /cdn/docs/invalidating-cached-content).
+func (c *UrlMapsClient) InvalidateCache(ctx context.Context, req *computepb.InvalidateCacheUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.InvalidateCache(ctx, req, opts...)
+}
+
+// List retrieves the list of UrlMap resources available to the specified project.
+func (c *UrlMapsClient) List(ctx context.Context, req *computepb.ListUrlMapsRequest, opts ...gax.CallOption) (*computepb.UrlMapList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Patch patches the specified UrlMap resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *UrlMapsClient) Patch(ctx context.Context, req *computepb.PatchUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Patch(ctx, req, opts...)
+}
+
+// Update updates the specified UrlMap resource with the data included in the request.
+func (c *UrlMapsClient) Update(ctx context.Context, req *computepb.UpdateUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Update(ctx, req, opts...)
+}
+
+// Validate runs static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap.
+func (c *UrlMapsClient) Validate(ctx context.Context, req *computepb.ValidateUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMapsValidateResponse, error) {
+	return c.internalClient.Validate(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type urlMapsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewUrlMapsRESTClient creates a new url maps rest client.
+//
+// The UrlMaps API.
+func NewUrlMapsRESTClient(ctx context.Context, opts ...option.ClientOption) (*UrlMapsClient, error) {
+	clientOpts := append(defaultUrlMapsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &urlMapsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &UrlMapsClient{internalClient: c, CallOptions: &UrlMapsCallOptions{}}, nil
+}
+
+func defaultUrlMapsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *urlMapsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *urlMapsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *urlMapsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves the list of all UrlMap resources, regional and global, available to the specified project.
+func (c *urlMapsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListUrlMapsRequest, opts ...gax.CallOption) (*computepb.UrlMapsAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/urlMaps", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMapsAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified UrlMap resource.
+func (c *urlMapsRESTClient) Delete(ctx context.Context, req *computepb.DeleteUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps/%v", req.GetProject(), req.GetUrlMap())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified UrlMap resource. Gets a list of available URL maps by making a list() request.
+func (c *urlMapsRESTClient) Get(ctx context.Context, req *computepb.GetUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMap, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps/%v", req.GetProject(), req.GetUrlMap())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMap{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a UrlMap resource in the specified project using the data included in the request.
+func (c *urlMapsRESTClient) Insert(ctx context.Context, req *computepb.InsertUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// InvalidateCache initiates a cache invalidation operation, invalidating the specified path, scoped to the specified UrlMap.
+//
+// For more information, see Invalidating cached content (at /cdn/docs/invalidating-cached-content).
+func (c *urlMapsRESTClient) InvalidateCache(ctx context.Context, req *computepb.InvalidateCacheUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetCacheInvalidationRuleResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps/%v/invalidateCache", req.GetProject(), req.GetUrlMap())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of UrlMap resources available to the specified project.
+func (c *urlMapsRESTClient) List(ctx context.Context, req *computepb.ListUrlMapsRequest, opts ...gax.CallOption) (*computepb.UrlMapList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMapList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Patch patches the specified UrlMap resource with the data included in the request. This method supports PATCH semantics and uses the JSON merge patch format and processing rules.
+func (c *urlMapsRESTClient) Patch(ctx context.Context, req *computepb.PatchUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps/%v", req.GetProject(), req.GetUrlMap())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PATCH", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Update updates the specified UrlMap resource with the data included in the request.
+func (c *urlMapsRESTClient) Update(ctx context.Context, req *computepb.UpdateUrlMapRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("")
+
+	params := url.Values{}
+	if req.GetProject() != "" {
+		params.Add("project", fmt.Sprintf("%v", req.GetProject()))
+	}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+	if req.GetUrlMap() != "" {
+		params.Add("urlMap", fmt.Sprintf("%v", req.GetUrlMap()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("PUT", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Validate runs static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap.
+func (c *urlMapsRESTClient) Validate(ctx context.Context, req *computepb.ValidateUrlMapRequest, opts ...gax.CallOption) (*computepb.UrlMapsValidateResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetUrlMapsValidateRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/global/urlMaps/%v/validate", req.GetProject(), req.GetUrlMap())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.UrlMapsValidateResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/url_maps_client_example_test.go b/compute/apiv1/url_maps_client_example_test.go
new file mode 100644
index 0000000..d6f8304
--- /dev/null
+++ b/compute/apiv1/url_maps_client_example_test.go
@@ -0,0 +1,207 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewUrlMapsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleUrlMapsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListUrlMapsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_InvalidateCache() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InvalidateCacheUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.InvalidateCache(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListUrlMapsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_Patch() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.PatchUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Patch(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_Update() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.UpdateUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Update(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleUrlMapsClient_Validate() {
+	ctx := context.Background()
+	c, err := compute.NewUrlMapsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ValidateUrlMapRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Validate(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/vpn_gateways_client.go b/compute/apiv1/vpn_gateways_client.go
new file mode 100644
index 0000000..80eb318
--- /dev/null
+++ b/compute/apiv1/vpn_gateways_client.go
@@ -0,0 +1,611 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newVpnGatewaysClientHook clientHook
+
+// VpnGatewaysCallOptions contains the retry settings for each method of VpnGatewaysClient.
+type VpnGatewaysCallOptions struct {
+	AggregatedList     []gax.CallOption
+	Delete             []gax.CallOption
+	Get                []gax.CallOption
+	GetStatus          []gax.CallOption
+	Insert             []gax.CallOption
+	List               []gax.CallOption
+	SetLabels          []gax.CallOption
+	TestIamPermissions []gax.CallOption
+}
+
+// internalVpnGatewaysClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalVpnGatewaysClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListVpnGatewaysRequest, ...gax.CallOption) (*computepb.VpnGatewayAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetVpnGatewayRequest, ...gax.CallOption) (*computepb.VpnGateway, error)
+	GetStatus(context.Context, *computepb.GetStatusVpnGatewayRequest, ...gax.CallOption) (*computepb.VpnGatewaysGetStatusResponse, error)
+	Insert(context.Context, *computepb.InsertVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListVpnGatewaysRequest, ...gax.CallOption) (*computepb.VpnGatewayList, error)
+	SetLabels(context.Context, *computepb.SetLabelsVpnGatewayRequest, ...gax.CallOption) (*computepb.Operation, error)
+	TestIamPermissions(context.Context, *computepb.TestIamPermissionsVpnGatewayRequest, ...gax.CallOption) (*computepb.TestPermissionsResponse, error)
+}
+
+// VpnGatewaysClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The VpnGateways API.
+type VpnGatewaysClient struct {
+	// The internal transport-dependent client.
+	internalClient internalVpnGatewaysClient
+
+	// The call options for this service.
+	CallOptions *VpnGatewaysCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *VpnGatewaysClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *VpnGatewaysClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *VpnGatewaysClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of VPN gateways.
+func (c *VpnGatewaysClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.VpnGatewayAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified VPN gateway.
+func (c *VpnGatewaysClient) Delete(ctx context.Context, req *computepb.DeleteVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified VPN gateway. Gets a list of available VPN gateways by making a list() request.
+func (c *VpnGatewaysClient) Get(ctx context.Context, req *computepb.GetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.VpnGateway, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// GetStatus returns the status for the specified VPN gateway.
+func (c *VpnGatewaysClient) GetStatus(ctx context.Context, req *computepb.GetStatusVpnGatewayRequest, opts ...gax.CallOption) (*computepb.VpnGatewaysGetStatusResponse, error) {
+	return c.internalClient.GetStatus(ctx, req, opts...)
+}
+
+// Insert creates a VPN gateway in the specified project and region using the data included in the request.
+func (c *VpnGatewaysClient) Insert(ctx context.Context, req *computepb.InsertVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of VPN gateways available to the specified project and region.
+func (c *VpnGatewaysClient) List(ctx context.Context, req *computepb.ListVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.VpnGatewayList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// SetLabels sets the labels on a VpnGateway. To learn more about labels, read the Labeling Resources documentation.
+func (c *VpnGatewaysClient) SetLabels(ctx context.Context, req *computepb.SetLabelsVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.SetLabels(ctx, req, opts...)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *VpnGatewaysClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsVpnGatewayRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	return c.internalClient.TestIamPermissions(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type vpnGatewaysRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewVpnGatewaysRESTClient creates a new vpn gateways rest client.
+//
+// The VpnGateways API.
+func NewVpnGatewaysRESTClient(ctx context.Context, opts ...option.ClientOption) (*VpnGatewaysClient, error) {
+	clientOpts := append(defaultVpnGatewaysRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &vpnGatewaysRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &VpnGatewaysClient{internalClient: c, CallOptions: &VpnGatewaysCallOptions{}}, nil
+}
+
+func defaultVpnGatewaysRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *vpnGatewaysRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *vpnGatewaysRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *vpnGatewaysRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of VPN gateways.
+func (c *vpnGatewaysRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.VpnGatewayAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/vpnGateways", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnGatewayAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified VPN gateway.
+func (c *vpnGatewaysRESTClient) Delete(ctx context.Context, req *computepb.DeleteVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways/%v", req.GetProject(), req.GetRegion(), req.GetVpnGateway())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified VPN gateway. Gets a list of available VPN gateways by making a list() request.
+func (c *vpnGatewaysRESTClient) Get(ctx context.Context, req *computepb.GetVpnGatewayRequest, opts ...gax.CallOption) (*computepb.VpnGateway, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways/%v", req.GetProject(), req.GetRegion(), req.GetVpnGateway())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnGateway{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// GetStatus returns the status for the specified VPN gateway.
+func (c *vpnGatewaysRESTClient) GetStatus(ctx context.Context, req *computepb.GetStatusVpnGatewayRequest, opts ...gax.CallOption) (*computepb.VpnGatewaysGetStatusResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways/%v/getStatus", req.GetProject(), req.GetRegion(), req.GetVpnGateway())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnGatewaysGetStatusResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a VPN gateway in the specified project and region using the data included in the request.
+func (c *vpnGatewaysRESTClient) Insert(ctx context.Context, req *computepb.InsertVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetVpnGatewayResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of VPN gateways available to the specified project and region.
+func (c *vpnGatewaysRESTClient) List(ctx context.Context, req *computepb.ListVpnGatewaysRequest, opts ...gax.CallOption) (*computepb.VpnGatewayList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnGatewayList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// SetLabels sets the labels on a VpnGateway. To learn more about labels, read the Labeling Resources documentation.
+func (c *vpnGatewaysRESTClient) SetLabels(ctx context.Context, req *computepb.SetLabelsVpnGatewayRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetRegionSetLabelsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways/%v/setLabels", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// TestIamPermissions returns permissions that a caller has on the specified resource.
+func (c *vpnGatewaysRESTClient) TestIamPermissions(ctx context.Context, req *computepb.TestIamPermissionsVpnGatewayRequest, opts ...gax.CallOption) (*computepb.TestPermissionsResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetTestPermissionsRequestResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnGateways/%v/testIamPermissions", req.GetProject(), req.GetRegion(), req.GetResource())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.TestPermissionsResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/vpn_gateways_client_example_test.go b/compute/apiv1/vpn_gateways_client_example_test.go
new file mode 100644
index 0000000..74b8ecf
--- /dev/null
+++ b/compute/apiv1/vpn_gateways_client_example_test.go
@@ -0,0 +1,188 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewVpnGatewaysRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleVpnGatewaysClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListVpnGatewaysRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_GetStatus() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetStatusVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetStatus(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListVpnGatewaysRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_SetLabels() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.SetLabelsVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.SetLabels(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnGatewaysClient_TestIamPermissions() {
+	ctx := context.Background()
+	c, err := compute.NewVpnGatewaysRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.TestIamPermissionsVpnGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.TestIamPermissions(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/vpn_tunnels_client.go b/compute/apiv1/vpn_tunnels_client.go
new file mode 100644
index 0000000..718d754
--- /dev/null
+++ b/compute/apiv1/vpn_tunnels_client.go
@@ -0,0 +1,452 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newVpnTunnelsClientHook clientHook
+
+// VpnTunnelsCallOptions contains the retry settings for each method of VpnTunnelsClient.
+type VpnTunnelsCallOptions struct {
+	AggregatedList []gax.CallOption
+	Delete         []gax.CallOption
+	Get            []gax.CallOption
+	Insert         []gax.CallOption
+	List           []gax.CallOption
+}
+
+// internalVpnTunnelsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalVpnTunnelsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	AggregatedList(context.Context, *computepb.AggregatedListVpnTunnelsRequest, ...gax.CallOption) (*computepb.VpnTunnelAggregatedList, error)
+	Delete(context.Context, *computepb.DeleteVpnTunnelRequest, ...gax.CallOption) (*computepb.Operation, error)
+	Get(context.Context, *computepb.GetVpnTunnelRequest, ...gax.CallOption) (*computepb.VpnTunnel, error)
+	Insert(context.Context, *computepb.InsertVpnTunnelRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListVpnTunnelsRequest, ...gax.CallOption) (*computepb.VpnTunnelList, error)
+}
+
+// VpnTunnelsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The VpnTunnels API.
+type VpnTunnelsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalVpnTunnelsClient
+
+	// The call options for this service.
+	CallOptions *VpnTunnelsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *VpnTunnelsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *VpnTunnelsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *VpnTunnelsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// AggregatedList retrieves an aggregated list of VPN tunnels.
+func (c *VpnTunnelsClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListVpnTunnelsRequest, opts ...gax.CallOption) (*computepb.VpnTunnelAggregatedList, error) {
+	return c.internalClient.AggregatedList(ctx, req, opts...)
+}
+
+// Delete deletes the specified VpnTunnel resource.
+func (c *VpnTunnelsClient) Delete(ctx context.Context, req *computepb.DeleteVpnTunnelRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get returns the specified VpnTunnel resource. Gets a list of available VPN tunnels by making a list() request.
+func (c *VpnTunnelsClient) Get(ctx context.Context, req *computepb.GetVpnTunnelRequest, opts ...gax.CallOption) (*computepb.VpnTunnel, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// Insert creates a VpnTunnel resource in the specified project and region using the data included in the request.
+func (c *VpnTunnelsClient) Insert(ctx context.Context, req *computepb.InsertVpnTunnelRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Insert(ctx, req, opts...)
+}
+
+// List retrieves a list of VpnTunnel resources contained in the specified project and region.
+func (c *VpnTunnelsClient) List(ctx context.Context, req *computepb.ListVpnTunnelsRequest, opts ...gax.CallOption) (*computepb.VpnTunnelList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type vpnTunnelsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewVpnTunnelsRESTClient creates a new vpn tunnels rest client.
+//
+// The VpnTunnels API.
+func NewVpnTunnelsRESTClient(ctx context.Context, opts ...option.ClientOption) (*VpnTunnelsClient, error) {
+	clientOpts := append(defaultVpnTunnelsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &vpnTunnelsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &VpnTunnelsClient{internalClient: c, CallOptions: &VpnTunnelsCallOptions{}}, nil
+}
+
+func defaultVpnTunnelsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *vpnTunnelsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *vpnTunnelsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *vpnTunnelsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// AggregatedList retrieves an aggregated list of VPN tunnels.
+func (c *vpnTunnelsRESTClient) AggregatedList(ctx context.Context, req *computepb.AggregatedListVpnTunnelsRequest, opts ...gax.CallOption) (*computepb.VpnTunnelAggregatedList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/aggregated/vpnTunnels", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.IncludeAllScopes != nil {
+		params.Add("includeAllScopes", fmt.Sprintf("%v", req.GetIncludeAllScopes()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnTunnelAggregatedList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Delete deletes the specified VpnTunnel resource.
+func (c *vpnTunnelsRESTClient) Delete(ctx context.Context, req *computepb.DeleteVpnTunnelRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnTunnels/%v", req.GetProject(), req.GetRegion(), req.GetVpnTunnel())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get returns the specified VpnTunnel resource. Gets a list of available VPN tunnels by making a list() request.
+func (c *vpnTunnelsRESTClient) Get(ctx context.Context, req *computepb.GetVpnTunnelRequest, opts ...gax.CallOption) (*computepb.VpnTunnel, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnTunnels/%v", req.GetProject(), req.GetRegion(), req.GetVpnTunnel())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnTunnel{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Insert creates a VpnTunnel resource in the specified project and region using the data included in the request.
+func (c *vpnTunnelsRESTClient) Insert(ctx context.Context, req *computepb.InsertVpnTunnelRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	body := req.GetVpnTunnelResource()
+	jsonReq, err := m.Marshal(body)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnTunnels", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.RequestId != nil {
+		params.Add("requestId", fmt.Sprintf("%v", req.GetRequestId()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of VpnTunnel resources contained in the specified project and region.
+func (c *vpnTunnelsRESTClient) List(ctx context.Context, req *computepb.ListVpnTunnelsRequest, opts ...gax.CallOption) (*computepb.VpnTunnelList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/regions/%v/vpnTunnels", req.GetProject(), req.GetRegion())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.VpnTunnelList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/vpn_tunnels_client_example_test.go b/compute/apiv1/vpn_tunnels_client_example_test.go
new file mode 100644
index 0000000..d5354e6
--- /dev/null
+++ b/compute/apiv1/vpn_tunnels_client_example_test.go
@@ -0,0 +1,131 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewVpnTunnelsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewVpnTunnelsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleVpnTunnelsClient_AggregatedList() {
+	ctx := context.Background()
+	c, err := compute.NewVpnTunnelsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.AggregatedListVpnTunnelsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.AggregatedList(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnTunnelsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewVpnTunnelsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteVpnTunnelRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnTunnelsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewVpnTunnelsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetVpnTunnelRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnTunnelsClient_Insert() {
+	ctx := context.Background()
+	c, err := compute.NewVpnTunnelsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.InsertVpnTunnelRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Insert(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleVpnTunnelsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewVpnTunnelsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListVpnTunnelsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/zone_operations_client.go b/compute/apiv1/zone_operations_client.go
new file mode 100644
index 0000000..e77c5b3
--- /dev/null
+++ b/compute/apiv1/zone_operations_client.go
@@ -0,0 +1,377 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newZoneOperationsClientHook clientHook
+
+// ZoneOperationsCallOptions contains the retry settings for each method of ZoneOperationsClient.
+type ZoneOperationsCallOptions struct {
+	Delete []gax.CallOption
+	Get    []gax.CallOption
+	List   []gax.CallOption
+	Wait   []gax.CallOption
+}
+
+// internalZoneOperationsClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalZoneOperationsClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Delete(context.Context, *computepb.DeleteZoneOperationRequest, ...gax.CallOption) (*computepb.DeleteZoneOperationResponse, error)
+	Get(context.Context, *computepb.GetZoneOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+	List(context.Context, *computepb.ListZoneOperationsRequest, ...gax.CallOption) (*computepb.OperationList, error)
+	Wait(context.Context, *computepb.WaitZoneOperationRequest, ...gax.CallOption) (*computepb.Operation, error)
+}
+
+// ZoneOperationsClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The ZoneOperations API.
+type ZoneOperationsClient struct {
+	// The internal transport-dependent client.
+	internalClient internalZoneOperationsClient
+
+	// The call options for this service.
+	CallOptions *ZoneOperationsCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ZoneOperationsClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ZoneOperationsClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ZoneOperationsClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Delete deletes the specified zone-specific Operations resource.
+func (c *ZoneOperationsClient) Delete(ctx context.Context, req *computepb.DeleteZoneOperationRequest, opts ...gax.CallOption) (*computepb.DeleteZoneOperationResponse, error) {
+	return c.internalClient.Delete(ctx, req, opts...)
+}
+
+// Get retrieves the specified zone-specific Operations resource.
+func (c *ZoneOperationsClient) Get(ctx context.Context, req *computepb.GetZoneOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves a list of Operation resources contained within the specified zone.
+func (c *ZoneOperationsClient) List(ctx context.Context, req *computepb.ListZoneOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Wait waits for the specified Operation resource to return as DONE or for the request to approach the 2 minute deadline, and retrieves the specified Operation resource. This method differs from the GET method in that it waits for no more than the default deadline (2 minutes) and then returns the current state of the operation, which might be DONE or still in progress.
+//
+// This method is called on a best-effort basis. Specifically:
+//
+//   In uncommon cases, when the server is overloaded, the request might return before the default deadline is reached, or might return after zero seconds.
+//
+//   If the default deadline is reached, there is no guarantee that the operation is actually done when the method returns. Be prepared to retry if the operation is not DONE.
+func (c *ZoneOperationsClient) Wait(ctx context.Context, req *computepb.WaitZoneOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	return c.internalClient.Wait(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type zoneOperationsRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewZoneOperationsRESTClient creates a new zone operations rest client.
+//
+// The ZoneOperations API.
+func NewZoneOperationsRESTClient(ctx context.Context, opts ...option.ClientOption) (*ZoneOperationsClient, error) {
+	clientOpts := append(defaultZoneOperationsRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &zoneOperationsRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ZoneOperationsClient{internalClient: c, CallOptions: &ZoneOperationsCallOptions{}}, nil
+}
+
+func defaultZoneOperationsRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *zoneOperationsRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *zoneOperationsRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *zoneOperationsRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Delete deletes the specified zone-specific Operations resource.
+func (c *zoneOperationsRESTClient) Delete(ctx context.Context, req *computepb.DeleteZoneOperationRequest, opts ...gax.CallOption) (*computepb.DeleteZoneOperationResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/operations/%v", req.GetProject(), req.GetZone(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("DELETE", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.DeleteZoneOperationResponse{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Get retrieves the specified zone-specific Operations resource.
+func (c *zoneOperationsRESTClient) Get(ctx context.Context, req *computepb.GetZoneOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/operations/%v", req.GetProject(), req.GetZone(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves a list of Operation resources contained within the specified zone.
+func (c *zoneOperationsRESTClient) List(ctx context.Context, req *computepb.ListZoneOperationsRequest, opts ...gax.CallOption) (*computepb.OperationList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/operations", req.GetProject(), req.GetZone())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.OperationList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// Wait waits for the specified Operation resource to return as DONE or for the request to approach the 2 minute deadline, and retrieves the specified Operation resource. This method differs from the GET method in that it waits for no more than the default deadline (2 minutes) and then returns the current state of the operation, which might be DONE or still in progress.
+//
+// This method is called on a best-effort basis. Specifically:
+//
+//   In uncommon cases, when the server is overloaded, the request might return before the default deadline is reached, or might return after zero seconds.
+//
+//   If the default deadline is reached, there is no guarantee that the operation is actually done when the method returns. Be prepared to retry if the operation is not DONE.
+func (c *zoneOperationsRESTClient) Wait(ctx context.Context, req *computepb.WaitZoneOperationRequest, opts ...gax.CallOption) (*computepb.Operation, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v/operations/%v/wait", req.GetProject(), req.GetZone(), req.GetOperation())
+
+	httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Operation{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/zone_operations_client_example_test.go b/compute/apiv1/zone_operations_client_example_test.go
new file mode 100644
index 0000000..f7f1c34
--- /dev/null
+++ b/compute/apiv1/zone_operations_client_example_test.go
@@ -0,0 +1,112 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewZoneOperationsRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewZoneOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleZoneOperationsClient_Delete() {
+	ctx := context.Background()
+	c, err := compute.NewZoneOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.DeleteZoneOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Delete(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleZoneOperationsClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewZoneOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetZoneOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleZoneOperationsClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewZoneOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListZoneOperationsRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleZoneOperationsClient_Wait() {
+	ctx := context.Background()
+	c, err := compute.NewZoneOperationsRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.WaitZoneOperationRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Wait(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/compute/apiv1/zones_client.go b/compute/apiv1/zones_client.go
new file mode 100644
index 0000000..bc02f75
--- /dev/null
+++ b/compute/apiv1/zones_client.go
@@ -0,0 +1,265 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	httptransport "google.golang.org/api/transport/http"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+var newZonesClientHook clientHook
+
+// ZonesCallOptions contains the retry settings for each method of ZonesClient.
+type ZonesCallOptions struct {
+	Get  []gax.CallOption
+	List []gax.CallOption
+}
+
+// internalZonesClient is an interface that defines the methods availaible from Google Compute Engine API.
+type internalZonesClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	Get(context.Context, *computepb.GetZoneRequest, ...gax.CallOption) (*computepb.Zone, error)
+	List(context.Context, *computepb.ListZonesRequest, ...gax.CallOption) (*computepb.ZoneList, error)
+}
+
+// ZonesClient is a client for interacting with Google Compute Engine API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// The Zones API.
+type ZonesClient struct {
+	// The internal transport-dependent client.
+	internalClient internalZonesClient
+
+	// The call options for this service.
+	CallOptions *ZonesCallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *ZonesClient) Close() error {
+	return c.internalClient.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *ZonesClient) setGoogleClientInfo(keyval ...string) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *ZonesClient) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// Get returns the specified Zone resource. Gets a list of available zones by making a list() request.
+func (c *ZonesClient) Get(ctx context.Context, req *computepb.GetZoneRequest, opts ...gax.CallOption) (*computepb.Zone, error) {
+	return c.internalClient.Get(ctx, req, opts...)
+}
+
+// List retrieves the list of Zone resources available to the specified project.
+func (c *ZonesClient) List(ctx context.Context, req *computepb.ListZonesRequest, opts ...gax.CallOption) (*computepb.ZoneList, error) {
+	return c.internalClient.List(ctx, req, opts...)
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type zonesRESTClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewZonesRESTClient creates a new zones rest client.
+//
+// The Zones API.
+func NewZonesRESTClient(ctx context.Context, opts ...option.ClientOption) (*ZonesClient, error) {
+	clientOpts := append(defaultZonesRESTClientOptions(), opts...)
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	c := &zonesRESTClient{
+		endpoint:   endpoint,
+		httpClient: httpClient,
+	}
+	c.setGoogleClientInfo()
+
+	return &ZonesClient{internalClient: c, CallOptions: &ZonesCallOptions{}}, nil
+}
+
+func defaultZonesRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("compute.googleapis.com"),
+		internaloption.WithDefaultMTLSEndpoint("compute.mtls.googleapis.com"),
+		internaloption.WithDefaultAudience("https://compute.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+	}
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *zonesRESTClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "rest", "UNKNOWN")
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *zonesRESTClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *zonesRESTClient) Connection() *grpc.ClientConn {
+	return nil
+}
+
+// Get returns the specified Zone resource. Gets a list of available zones by making a list() request.
+func (c *zonesRESTClient) Get(ctx context.Context, req *computepb.GetZoneRequest, opts ...gax.CallOption) (*computepb.Zone, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones/%v", req.GetProject(), req.GetZone())
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.Zone{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
+
+// List retrieves the list of Zone resources available to the specified project.
+func (c *zonesRESTClient) List(ctx context.Context, req *computepb.ListZonesRequest, opts ...gax.CallOption) (*computepb.ZoneList, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, _ := url.Parse(c.endpoint)
+	baseUrl.Path += fmt.Sprintf("/compute/v1/projects/%v/zones", req.GetProject())
+
+	params := url.Values{}
+	if req != nil && req.Filter != nil {
+		params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+	}
+	if req != nil && req.MaxResults != nil {
+		params.Add("maxResults", fmt.Sprintf("%v", req.GetMaxResults()))
+	}
+	if req != nil && req.OrderBy != nil {
+		params.Add("orderBy", fmt.Sprintf("%v", req.GetOrderBy()))
+	}
+	if req != nil && req.PageToken != nil {
+		params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+	}
+	if req != nil && req.ReturnPartialSuccess != nil {
+		params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+	}
+
+	baseUrl.RawQuery = params.Encode()
+
+	httpReq, err := http.NewRequest("GET", baseUrl.String(), bytes.NewReader(jsonReq))
+	if err != nil {
+		return nil, err
+	}
+	httpReq = httpReq.WithContext(ctx)
+	// Set the headers
+	for k, v := range c.xGoogMetadata {
+		httpReq.Header[k] = v
+	}
+	httpReq.Header["Content-Type"] = []string{"application/json"}
+
+	httpRsp, err := c.httpClient.Do(httpReq)
+	if err != nil {
+		return nil, err
+	}
+	defer httpRsp.Body.Close()
+
+	if httpRsp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf(httpRsp.Status)
+	}
+
+	buf, err := ioutil.ReadAll(httpRsp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	rsp := &computepb.ZoneList{}
+
+	return rsp, unm.Unmarshal(buf, rsp)
+}
diff --git a/compute/apiv1/zones_client_example_test.go b/compute/apiv1/zones_client_example_test.go
new file mode 100644
index 0000000..109f470
--- /dev/null
+++ b/compute/apiv1/zones_client_example_test.go
@@ -0,0 +1,74 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package compute_test
+
+import (
+	"context"
+
+	compute "cloud.google.com/go/compute/apiv1"
+	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
+)
+
+func ExampleNewZonesRESTClient() {
+	ctx := context.Background()
+	c, err := compute.NewZonesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleZonesClient_Get() {
+	ctx := context.Background()
+	c, err := compute.NewZonesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.GetZoneRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.Get(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleZonesClient_List() {
+	ctx := context.Background()
+	c, err := compute.NewZonesRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &computepb.ListZonesRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.List(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
diff --git a/internal/.repo-metadata-full.json b/internal/.repo-metadata-full.json
index 1d782dd..4e9f7ec 100644
--- a/internal/.repo-metadata-full.json
+++ b/internal/.repo-metadata-full.json
@@ -314,6 +314,15 @@
     "release_level": "beta",
     "library_type": ""
   },
+  "cloud.google.com/go/compute/apiv1": {
+    "distribution_name": "cloud.google.com/go/compute/apiv1",
+    "description": "Google Compute Engine API",
+    "language": "Go",
+    "client_library_type": "generated",
+    "docs_url": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/latest/compute/apiv1",
+    "release_level": "alpha",
+    "library_type": ""
+  },
   "cloud.google.com/go/compute/metadata": {
     "distribution_name": "cloud.google.com/go/compute/metadata",
     "description": "Service Metadata API",
