Change the way to support custom gob encoder and decoder.
Use public structs instead of manually encoding/decoding
individual unexported fields to fully utilize the capability
of Gob's default encoder and decoder.
Bug: 358427516
Test: manual tests and CI.
Change-Id: I5f5b6c8368e6449acc45c8c492777329636b3d41
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index 38f1382..d28831e 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -17,7 +17,6 @@
import (
"bytes"
"encoding/csv"
- "encoding/gob"
"fmt"
"slices"
"strconv"
@@ -126,32 +125,32 @@
properties map[string]string
}
+type complianceMetadataInfoGob struct {
+ Properties map[string]string
+}
+
func NewComplianceMetadataInfo() *ComplianceMetadataInfo {
return &ComplianceMetadataInfo{
properties: map[string]string{},
}
}
-func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := encoder.Encode(c.properties)
- if err != nil {
- return nil, err
+func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob {
+ return &complianceMetadataInfoGob{
+ Properties: m.properties,
}
+}
- return w.Bytes(), nil
+func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) {
+ m.properties = data.Properties
+}
+
+func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[complianceMetadataInfoGob](c)
}
func (c *ComplianceMetadataInfo) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := decoder.Decode(&c.properties)
- if err != nil {
- return err
- }
-
- return nil
+ return blueprint.CustomGobDecode[complianceMetadataInfoGob](data, c)
}
func (c *ComplianceMetadataInfo) SetStringValue(propertyName string, value string) {
diff --git a/android/depset_generic.go b/android/depset_generic.go
index 690987a..d04f88b 100644
--- a/android/depset_generic.go
+++ b/android/depset_generic.go
@@ -15,10 +15,9 @@
package android
import (
- "bytes"
- "encoding/gob"
- "errors"
"fmt"
+
+ "github.com/google/blueprint"
)
// DepSet is designed to be conceptually compatible with Bazel's depsets:
@@ -68,28 +67,38 @@
transitive []*DepSet[T]
}
-func (d *DepSet[T]) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(d.preorder), encoder.Encode(d.reverse),
- encoder.Encode(d.order), encoder.Encode(d.direct), encoder.Encode(d.transitive))
- if err != nil {
- return nil, err
- }
+type depSetGob[T depSettableType] struct {
+ Preorder bool
+ Reverse bool
+ Order DepSetOrder
+ Direct []T
+ Transitive []*DepSet[T]
+}
- return w.Bytes(), nil
+func (d *DepSet[T]) ToGob() *depSetGob[T] {
+ return &depSetGob[T]{
+ Preorder: d.preorder,
+ Reverse: d.reverse,
+ Order: d.order,
+ Direct: d.direct,
+ Transitive: d.transitive,
+ }
+}
+
+func (d *DepSet[T]) FromGob(data *depSetGob[T]) {
+ d.preorder = data.Preorder
+ d.reverse = data.Reverse
+ d.order = data.Order
+ d.direct = data.Direct
+ d.transitive = data.Transitive
+}
+
+func (d *DepSet[T]) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[depSetGob[T]](d)
}
func (d *DepSet[T]) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&d.preorder), decoder.Decode(&d.reverse),
- decoder.Decode(&d.order), decoder.Decode(&d.direct), decoder.Decode(&d.transitive))
- if err != nil {
- return err
- }
-
- return nil
+ return blueprint.CustomGobDecode[depSetGob[T]](data, d)
}
// NewDepSet returns an immutable DepSet with the given order, direct and transitive contents.
diff --git a/android/init.go b/android/init.go
index b462292..1ace344 100644
--- a/android/init.go
+++ b/android/init.go
@@ -17,7 +17,12 @@
import "encoding/gob"
func init() {
+ gob.Register(extraFilesZip{})
+ gob.Register(InstallPath{})
+ gob.Register(ModuleGenPath{})
gob.Register(ModuleOutPath{})
+ gob.Register(OutputPath{})
gob.Register(PhonyPath{})
+ gob.Register(SourcePath{})
gob.Register(unstableInfo{})
}
diff --git a/android/module.go b/android/module.go
index a1a9a4a..82b3781 100644
--- a/android/module.go
+++ b/android/module.go
@@ -15,9 +15,6 @@
package android
import (
- "bytes"
- "encoding/gob"
- "errors"
"fmt"
"net/url"
"path/filepath"
@@ -2130,36 +2127,47 @@
orderOnlyDeps Paths
executable bool
extraFiles *extraFilesZip
-
- absFrom string
+ absFrom string
}
-func (p *katiInstall) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(p.from), encoder.Encode(p.to),
- encoder.Encode(p.implicitDeps), encoder.Encode(p.orderOnlyDeps),
- encoder.Encode(p.executable), encoder.Encode(p.extraFiles),
- encoder.Encode(p.absFrom))
- if err != nil {
- return nil, err
- }
-
- return w.Bytes(), nil
+type katiInstallGob struct {
+ From Path
+ To InstallPath
+ ImplicitDeps Paths
+ OrderOnlyDeps Paths
+ Executable bool
+ ExtraFiles *extraFilesZip
+ AbsFrom string
}
-func (p *katiInstall) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&p.from), decoder.Decode(&p.to),
- decoder.Decode(&p.implicitDeps), decoder.Decode(&p.orderOnlyDeps),
- decoder.Decode(&p.executable), decoder.Decode(&p.extraFiles),
- decoder.Decode(&p.absFrom))
- if err != nil {
- return err
+func (k *katiInstall) ToGob() *katiInstallGob {
+ return &katiInstallGob{
+ From: k.from,
+ To: k.to,
+ ImplicitDeps: k.implicitDeps,
+ OrderOnlyDeps: k.orderOnlyDeps,
+ Executable: k.executable,
+ ExtraFiles: k.extraFiles,
+ AbsFrom: k.absFrom,
}
+}
- return nil
+func (k *katiInstall) FromGob(data *katiInstallGob) {
+ k.from = data.From
+ k.to = data.To
+ k.implicitDeps = data.ImplicitDeps
+ k.orderOnlyDeps = data.OrderOnlyDeps
+ k.executable = data.Executable
+ k.extraFiles = data.ExtraFiles
+ k.absFrom = data.AbsFrom
+}
+
+func (k *katiInstall) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[katiInstallGob](k)
+}
+
+func (k *katiInstall) GobDecode(data []byte) error {
+ return blueprint.CustomGobDecode[katiInstallGob](data, k)
}
type extraFilesZip struct {
@@ -2167,26 +2175,29 @@
dir InstallPath
}
-func (p *extraFilesZip) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(p.zip), encoder.Encode(p.dir))
- if err != nil {
- return nil, err
- }
-
- return w.Bytes(), nil
+type extraFilesZipGob struct {
+ Zip Path
+ Dir InstallPath
}
-func (p *extraFilesZip) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&p.zip), decoder.Decode(&p.dir))
- if err != nil {
- return err
+func (e *extraFilesZip) ToGob() *extraFilesZipGob {
+ return &extraFilesZipGob{
+ Zip: e.zip,
+ Dir: e.dir,
}
+}
- return nil
+func (e *extraFilesZip) FromGob(data *extraFilesZipGob) {
+ e.zip = data.Zip
+ e.dir = data.Dir
+}
+
+func (e *extraFilesZip) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[extraFilesZipGob](e)
+}
+
+func (e *extraFilesZip) GobDecode(data []byte) error {
+ return blueprint.CustomGobDecode[extraFilesZipGob](data, e)
}
type katiInstalls []katiInstall
diff --git a/android/packaging.go b/android/packaging.go
index 0909936..3c64d56 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -15,9 +15,6 @@
package android
import (
- "bytes"
- "encoding/gob"
- "errors"
"fmt"
"path/filepath"
"sort"
@@ -67,34 +64,53 @@
owner string
}
-func (p *PackagingSpec) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(p.relPathInPackage), encoder.Encode(p.srcPath),
- encoder.Encode(p.symlinkTarget), encoder.Encode(p.executable),
- encoder.Encode(p.effectiveLicenseFiles), encoder.Encode(p.partition),
- encoder.Encode(p.skipInstall), encoder.Encode(p.aconfigPaths),
- encoder.Encode(p.archType))
- if err != nil {
- return nil, err
- }
+type packagingSpecGob struct {
+ RelPathInPackage string
+ SrcPath Path
+ SymlinkTarget string
+ Executable bool
+ Partition string
+ SkipInstall bool
+ AconfigPaths *Paths
+ ArchType ArchType
+ Overrides *[]string
+ Owner string
+}
- return w.Bytes(), nil
+func (p *PackagingSpec) ToGob() *packagingSpecGob {
+ return &packagingSpecGob{
+ RelPathInPackage: p.relPathInPackage,
+ SrcPath: p.srcPath,
+ SymlinkTarget: p.symlinkTarget,
+ Executable: p.executable,
+ Partition: p.partition,
+ SkipInstall: p.skipInstall,
+ AconfigPaths: p.aconfigPaths,
+ ArchType: p.archType,
+ Overrides: p.overrides,
+ Owner: p.owner,
+ }
+}
+
+func (p *PackagingSpec) FromGob(data *packagingSpecGob) {
+ p.relPathInPackage = data.RelPathInPackage
+ p.srcPath = data.SrcPath
+ p.symlinkTarget = data.SymlinkTarget
+ p.executable = data.Executable
+ p.partition = data.Partition
+ p.skipInstall = data.SkipInstall
+ p.aconfigPaths = data.AconfigPaths
+ p.archType = data.ArchType
+ p.overrides = data.Overrides
+ p.owner = data.Owner
+}
+
+func (p *PackagingSpec) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[packagingSpecGob](p)
}
func (p *PackagingSpec) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&p.relPathInPackage), decoder.Decode(&p.srcPath),
- decoder.Decode(&p.symlinkTarget), decoder.Decode(&p.executable),
- decoder.Decode(&p.effectiveLicenseFiles), decoder.Decode(&p.partition),
- decoder.Decode(&p.skipInstall), decoder.Decode(&p.aconfigPaths),
- decoder.Decode(&p.archType))
- if err != nil {
- return err
- }
-
- return nil
+ return blueprint.CustomGobDecode[packagingSpecGob](data, p)
}
func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
diff --git a/android/paths.go b/android/paths.go
index 1c8258e..9c2df65 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -15,9 +15,6 @@
package android
import (
- "bytes"
- "encoding/gob"
- "errors"
"fmt"
"os"
"path/filepath"
@@ -342,6 +339,11 @@
invalidReason string // Not applicable if path != nil. "" if the reason is unknown.
}
+type optionalPathGob struct {
+ Path Path
+ InvalidReason string
+}
+
// OptionalPathForPath returns an OptionalPath containing the path.
func OptionalPathForPath(path Path) OptionalPath {
return OptionalPath{path: path}
@@ -353,6 +355,26 @@
return OptionalPath{invalidReason: reason}
}
+func (p *OptionalPath) ToGob() *optionalPathGob {
+ return &optionalPathGob{
+ Path: p.path,
+ InvalidReason: p.invalidReason,
+ }
+}
+
+func (p *OptionalPath) FromGob(data *optionalPathGob) {
+ p.path = data.Path
+ p.invalidReason = data.InvalidReason
+}
+
+func (p OptionalPath) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[optionalPathGob](&p)
+}
+
+func (p *OptionalPath) GobDecode(data []byte) error {
+ return blueprint.CustomGobDecode[optionalPathGob](data, p)
+}
+
// Valid returns whether there is a valid path
func (p OptionalPath) Valid() bool {
return p.path != nil
@@ -1065,26 +1087,29 @@
rel string
}
-func (p basePath) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(p.path), encoder.Encode(p.rel))
- if err != nil {
- return nil, err
- }
+type basePathGob struct {
+ Path string
+ Rel string
+}
- return w.Bytes(), nil
+func (p *basePath) ToGob() *basePathGob {
+ return &basePathGob{
+ Path: p.path,
+ Rel: p.rel,
+ }
+}
+
+func (p *basePath) FromGob(data *basePathGob) {
+ p.path = data.Path
+ p.rel = data.Rel
+}
+
+func (p basePath) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[basePathGob](&p)
}
func (p *basePath) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&p.path), decoder.Decode(&p.rel))
- if err != nil {
- return err
- }
-
- return nil
+ return blueprint.CustomGobDecode[basePathGob](data, p)
}
func (p basePath) Ext() string {
@@ -1337,26 +1362,32 @@
fullPath string
}
-func (p OutputPath) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.outDir), encoder.Encode(p.fullPath))
- if err != nil {
- return nil, err
- }
+type outputPathGob struct {
+ basePath
+ OutDir string
+ FullPath string
+}
- return w.Bytes(), nil
+func (p *OutputPath) ToGob() *outputPathGob {
+ return &outputPathGob{
+ basePath: p.basePath,
+ OutDir: p.outDir,
+ FullPath: p.fullPath,
+ }
+}
+
+func (p *OutputPath) FromGob(data *outputPathGob) {
+ p.basePath = data.basePath
+ p.outDir = data.OutDir
+ p.fullPath = data.FullPath
+}
+
+func (p OutputPath) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[outputPathGob](&p)
}
func (p *OutputPath) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.outDir), decoder.Decode(&p.fullPath))
- if err != nil {
- return err
- }
-
- return nil
+ return blueprint.CustomGobDecode[outputPathGob](data, p)
}
func (p OutputPath) withRel(rel string) OutputPath {
@@ -1756,30 +1787,41 @@
fullPath string
}
-func (p *InstallPath) GobEncode() ([]byte, error) {
- w := new(bytes.Buffer)
- encoder := gob.NewEncoder(w)
- err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.soongOutDir),
- encoder.Encode(p.partitionDir), encoder.Encode(p.partition),
- encoder.Encode(p.makePath), encoder.Encode(p.fullPath))
- if err != nil {
- return nil, err
- }
+type installPathGob struct {
+ basePath
+ SoongOutDir string
+ PartitionDir string
+ Partition string
+ MakePath bool
+ FullPath string
+}
- return w.Bytes(), nil
+func (p *InstallPath) ToGob() *installPathGob {
+ return &installPathGob{
+ basePath: p.basePath,
+ SoongOutDir: p.soongOutDir,
+ PartitionDir: p.partitionDir,
+ Partition: p.partition,
+ MakePath: p.makePath,
+ FullPath: p.fullPath,
+ }
+}
+
+func (p *InstallPath) FromGob(data *installPathGob) {
+ p.basePath = data.basePath
+ p.soongOutDir = data.SoongOutDir
+ p.partitionDir = data.PartitionDir
+ p.partition = data.Partition
+ p.makePath = data.MakePath
+ p.fullPath = data.FullPath
+}
+
+func (p InstallPath) GobEncode() ([]byte, error) {
+ return blueprint.CustomGobEncode[installPathGob](&p)
}
func (p *InstallPath) GobDecode(data []byte) error {
- r := bytes.NewBuffer(data)
- decoder := gob.NewDecoder(r)
- err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.soongOutDir),
- decoder.Decode(&p.partitionDir), decoder.Decode(&p.partition),
- decoder.Decode(&p.makePath), decoder.Decode(&p.fullPath))
- if err != nil {
- return err
- }
-
- return nil
+ return blueprint.CustomGobDecode[installPathGob](data, p)
}
// Will panic if called from outside a test environment.