bigquery: add Description field for routines.

Initially, Routines (currently UDFs and stored procedures) did not
support a description field.  This change adds support for leveraging
description fields.

Change-Id: I75eb1e081e50923569a61ea640aa621c505ae909
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/48250
Reviewed-by: Alex Hong <hongalex@google.com>
Reviewed-by: kokoro <noreply+kokoro@google.com>
diff --git a/bigquery/integration_test.go b/bigquery/integration_test.go
index eeb1876..cc5e33b 100644
--- a/bigquery/integration_test.go
+++ b/bigquery/integration_test.go
@@ -2472,20 +2472,25 @@
 		t.Errorf("Language mismatch. got %s want %s", curMeta.Language, want)
 	}
 
-	// Perform an update to change the routine body.
+	// Perform an update to change the routine body and description.
 	want = "x * 4"
+	wantDescription := "an updated description"
 	// during beta, update doesn't allow partial updates.  Provide all fields.
 	newMeta, err := routine.Update(ctx, &RoutineMetadataToUpdate{
-		Body:       want,
-		Arguments:  curMeta.Arguments,
-		ReturnType: curMeta.ReturnType,
-		Type:       curMeta.Type,
+		Body:        want,
+		Arguments:   curMeta.Arguments,
+		Description: wantDescription,
+		ReturnType:  curMeta.ReturnType,
+		Type:        curMeta.Type,
 	}, curMeta.ETag)
 	if err != nil {
 		t.Fatalf("Update: %v", err)
 	}
 	if newMeta.Body != want {
-		t.Fatalf("Update failed.  want %s got %s", want, newMeta.Body)
+		t.Fatalf("Update body failed. want %s got %s", want, newMeta.Body)
+	}
+	if newMeta.Description != wantDescription {
+		t.Fatalf("Update description failed. want %s got %s", wantDescription, newMeta.Description)
 	}
 
 	// Ensure presence when enumerating the model list.
diff --git a/bigquery/routine.go b/bigquery/routine.go
index 0bb6c05..c045b64 100644
--- a/bigquery/routine.go
+++ b/bigquery/routine.go
@@ -127,6 +127,7 @@
 	// Type indicates the type of routine, such as SCALAR_FUNCTION or PROCEDURE.
 	Type             string
 	CreationTime     time.Time
+	Description      string
 	LastModifiedTime time.Time
 	// Language of the routine, such as SQL or JAVASCRIPT.
 	Language string
@@ -151,6 +152,7 @@
 	if rm == nil {
 		return r, nil
 	}
+	r.Description = rm.Description
 	r.Language = rm.Language
 	r.RoutineType = rm.Type
 	r.DefinitionBody = rm.Body
@@ -264,6 +266,7 @@
 // RoutineMetadataToUpdate governs updating a routine.
 type RoutineMetadataToUpdate struct {
 	Arguments         []*RoutineArgument
+	Description       optional.String
 	Type              optional.String
 	Language          optional.String
 	Body              optional.String
@@ -279,6 +282,10 @@
 	nullField := func(field string) {
 		r.NullFields = append(r.NullFields, field)
 	}
+	if rm.Description != nil {
+		r.Description = optional.ToString(rm.Description)
+		forceSend("Description")
+	}
 	if rm.Arguments != nil {
 		if len(rm.Arguments) == 0 {
 			nullField("Arguments")
@@ -327,6 +334,7 @@
 		ETag:              r.Etag,
 		Type:              r.RoutineType,
 		CreationTime:      unixMillisToTime(r.CreationTime),
+		Description:       r.Description,
 		LastModifiedTime:  unixMillisToTime(r.LastModifiedTime),
 		Language:          r.Language,
 		ImportedLibraries: r.ImportedLibraries,
diff --git a/bigquery/routine_test.go b/bigquery/routine_test.go
index 40a6757..5f027fe 100644
--- a/bigquery/routine_test.go
+++ b/bigquery/routine_test.go
@@ -78,6 +78,7 @@
 				CreationTime:     aTimeMillis,
 				LastModifiedTime: aTimeMillis,
 				DefinitionBody:   "body",
+				Description:      "desc",
 				Etag:             "etag",
 				RoutineType:      "type",
 				Language:         "lang",
@@ -85,6 +86,7 @@
 			&RoutineMetadata{
 				CreationTime:     aTime,
 				LastModifiedTime: aTime,
+				Description:      "desc",
 				Body:             "body",
 				ETag:             "etag",
 				Type:             "type",