internal/{report,worker}: replace calls of XToReport with report.New

Use report.New instead of individual implementations of ToReport in
code and tests. This will allow us to move logic shared between different
vuln sources to the report.New function.

Change-Id: I1817ba0664f592ba9646617237b0a6ce826ca89c
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/579857
Commit-Queue: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/genericosv/report_test.go b/internal/genericosv/report_test.go
index 864c67f..c4f82ab 100644
--- a/internal/genericosv/report_test.go
+++ b/internal/genericosv/report_test.go
@@ -49,13 +49,13 @@
 				t.Fatal(err)
 			}
 
-			osv := Entry{}
-			if err := report.UnmarshalFromFile(path, &osv); err != nil {
+			osv := &Entry{}
+			if err := report.UnmarshalFromFile(path, osv); err != nil {
 				t.Fatal(err)
 			}
 
-			modulePath := "" // ignored by ToReport
-			got := osv.ToReport("GO-TEST-ID", modulePath, pc)
+			modulePath := "" // ignored
+			got := report.New(osv, "GO-TEST-ID", modulePath, pc)
 			// Keep record of what lints would apply to each generated report.
 			got.LintAsNotes(pc)
 
diff --git a/internal/report/cve.go b/internal/report/cve.go
index 42f41bc..6cfdebc 100644
--- a/internal/report/cve.go
+++ b/internal/report/cve.go
@@ -34,8 +34,8 @@
 	return newlines.ReplaceAllString(strings.TrimSpace(s), " ")
 }
 
-// CVEToReport creates a Report struct from a given CVE and modulePath.
-func CVEToReport(c *cveschema.CVE, id, modulePath string, pc *proxy.Client) *Report {
+// cveToReport creates a Report struct from a given CVE and modulePath.
+func cveToReport(c *cveschema.CVE, id, modulePath string, pc *proxy.Client) *Report {
 	var description Description
 	for _, d := range c.Description.Data {
 		description += Description(d.Value + "\n")
@@ -108,7 +108,7 @@
 	r.CVEs = append(r.CVEs, cveID)
 }
 
-func CVE5ToReport(c *cveschema5.CVERecord, id, modulePath string, pc *proxy.Client) *Report {
+func cve5ToReport(c *cveschema5.CVERecord, id, modulePath string, pc *proxy.Client) *Report {
 	cna := c.Containers.CNAContainer
 
 	var description Description
diff --git a/internal/report/cve_test.go b/internal/report/cve_test.go
index 41c62f5..002f5f9 100644
--- a/internal/report/cve_test.go
+++ b/internal/report/cve_test.go
@@ -91,7 +91,7 @@
 		return new(cveschema.CVE)
 	}
 	toReportV4 := func(cve cvelistrepo.CVE, modulePath string) *Report {
-		return CVEToReport(cve.(*cveschema.CVE), placeholderID, modulePath, pc)
+		return New(ToCVE4(cve.(*cveschema.CVE)), placeholderID, modulePath, pc)
 	}
 	if err := run(t, v4txtar, newV4, toReportV4); err != nil {
 		t.Fatal(err)
@@ -108,7 +108,7 @@
 		return new(cveschema5.CVERecord)
 	}
 	toReportV5 := func(cve cvelistrepo.CVE, modulePath string) *Report {
-		return CVE5ToReport(cve.(*cveschema5.CVERecord), placeholderID, modulePath, pc)
+		return New(ToCVE5(cve.(*cveschema5.CVERecord)), placeholderID, modulePath, pc)
 	}
 	if err := run(t, v5txtar, newV5, toReportV5); err != nil {
 		t.Fatal(err)
diff --git a/internal/report/ghsa.go b/internal/report/ghsa.go
index c0d4099..e5cb7a8 100644
--- a/internal/report/ghsa.go
+++ b/internal/report/ghsa.go
@@ -12,8 +12,8 @@
 	"golang.org/x/vulndb/internal/proxy"
 )
 
-// GHSAToReport creates a Report struct from a given GHSA SecurityAdvisory and modulePath.
-func GHSAToReport(sa *ghsa.SecurityAdvisory, modulePath string, pc *proxy.Client) *Report {
+// ghsaToReport creates a Report struct from a given GHSA SecurityAdvisory and modulePath.
+func ghsaToReport(sa *ghsa.SecurityAdvisory, modulePath string, pc *proxy.Client) *Report {
 	r := &Report{
 		Summary:     Summary(sa.Summary),
 		Description: Description(sa.Description),
diff --git a/internal/report/ghsa_test.go b/internal/report/ghsa_test.go
index bcbf197..3e775a4 100644
--- a/internal/report/ghsa_test.go
+++ b/internal/report/ghsa_test.go
@@ -43,6 +43,7 @@
 			name:   "module provided",
 			module: "golang.org/x/tools",
 			want: &Report{
+				ID: placeholderID,
 				Modules: []*Module{{
 					Module:       "golang.org/x/tools",
 					VulnerableAt: "0.8.0",
@@ -65,6 +66,7 @@
 			name:   "empty module uses package as module",
 			module: "",
 			want: &Report{
+				ID: placeholderID,
 				Modules: []*Module{{
 					Module: "golang.org/x/tools/go/packages",
 					Versions: []VersionRange{
@@ -85,7 +87,7 @@
 	} {
 		test := test
 		t.Run(test.name, func(t *testing.T) {
-			got := GHSAToReport(sa, test.module, pc)
+			got := New(ToLegacyGHSA(sa), placeholderID, test.module, pc)
 			if diff := cmp.Diff(*got, *test.want); diff != "" {
 				t.Errorf("mismatch (-want, +got):\n%s", diff)
 			}
diff --git a/internal/report/new.go b/internal/report/new.go
index e8fa425..7b78d04 100644
--- a/internal/report/new.go
+++ b/internal/report/new.go
@@ -37,8 +37,12 @@
 
 var _ Source = &cve5{}
 
+func ToCVE5(c *cveschema5.CVERecord) Source {
+	return &cve5{CVERecord: c}
+}
+
 func (c *cve5) ToReport(goID, modulePath string, pc *proxy.Client) *Report {
-	return CVE5ToReport(c.CVERecord, goID, modulePath, pc)
+	return cve5ToReport(c.CVERecord, goID, modulePath, pc)
 }
 
 func (c *cve5) SourceID() string {
@@ -63,13 +67,18 @@
 //
 // Note: Fetch is not implemented for CVE4, as it is a legacy format
 // which will be phased out soon.
-type cve4 cveschema.CVE
+type cve4 struct {
+	*cveschema.CVE
+}
 
 var _ Source = &cve4{}
 
+func ToCVE4(c *cveschema.CVE) Source {
+	return &cve4{CVE: c}
+}
+
 func (c *cve4) ToReport(goID, modulePath string, pc *proxy.Client) *Report {
-	cve := cveschema.CVE(*c)
-	return CVEToReport(&cve, goID, modulePath, pc)
+	return cveToReport(c.CVE, goID, modulePath, pc)
 }
 
 func (c *cve4) SourceID() string {
@@ -87,8 +96,14 @@
 
 var _ Source = &legacyGHSA{}
 
+func ToLegacyGHSA(g *ghsa.SecurityAdvisory) Source {
+	return &legacyGHSA{
+		SecurityAdvisory: g,
+	}
+}
+
 func (g *legacyGHSA) ToReport(goID, modulePath string, pc *proxy.Client) *Report {
-	r := GHSAToReport(g.SecurityAdvisory, modulePath, pc)
+	r := ghsaToReport(g.SecurityAdvisory, modulePath, pc)
 	r.ID = goID
 	return r
 }
diff --git a/internal/worker/worker.go b/internal/worker/worker.go
index 3168d9d..b950d7f 100644
--- a/internal/worker/worker.go
+++ b/internal/worker/worker.go
@@ -256,6 +256,8 @@
 	return nil
 }
 
+const pendingID = "GO-ID-PENDING"
+
 func newCVEBody(sr storeRecord, rc *report.Client, pc *proxy.Client) (string, error) {
 	cr := sr.(*store.CVERecord)
 	var b strings.Builder
@@ -265,7 +267,7 @@
 	if cr.CVE.Metadata.ID == "" {
 		cr.CVE.Metadata.ID = cr.ID
 	}
-	r := report.CVEToReport(cr.CVE, "GO-ID-PENDING", cr.Module, pc)
+	r := report.New(report.ToCVE4(cr.CVE), pendingID, cr.Module, pc)
 	r.Description = ""
 	out, err := r.ToString()
 	if err != nil {
@@ -365,7 +367,7 @@
 }
 
 func isDuplicate(sa *ghsa.SecurityAdvisory, pc *proxy.Client, rc *report.Client) bool {
-	r := report.GHSAToReport(sa, "", pc)
+	r := report.New(report.ToLegacyGHSA(sa), pendingID, "", pc)
 	for _, aliases := range rc.XRef(r) {
 		if slices.Contains(aliases, sa.ID) {
 			return true
@@ -375,7 +377,7 @@
 }
 
 func CreateGHSABody(sa *ghsa.SecurityAdvisory, rc *report.Client, pc *proxy.Client) (body string, err error) {
-	r := report.GHSAToReport(sa, "", pc)
+	r := report.New(report.ToLegacyGHSA(sa), pendingID, "", pc)
 	r.Description = ""
 	rs, err := r.ToString()
 	if err != nil {
diff --git a/internal/worker/worker_test.go b/internal/worker/worker_test.go
index 78d1cf9..1a194b3 100644
--- a/internal/worker/worker_test.go
+++ b/internal/worker/worker_test.go
@@ -358,6 +358,7 @@
 See [doc/triage.md](https://github.com/golang/vulndb/blob/master/doc/triage.md) for instructions on how to triage this report.
 
 ` + "```" + `
+id: GO-ID-PENDING
 modules:
     - module: aPackage
       versions: