From a8d446d548e4cfda41570959bd99c90365c2b995 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Wed, 4 Jan 2023 09:09:23 +1100 Subject: [PATCH] types/known/structpb: preallocate map in AsMap Change-Id: I4fe676418959c23055e91d99a07ee3be8d466e25 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/460215 Reviewed-by: Damien Neil Reviewed-by: Joseph Tsai Reviewed-by: Michael Stapelberg --- .../internal_gengo/well_known_types.go | 17 ++++++++--------- types/known/structpb/struct.pb.go | 17 ++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/cmd/protoc-gen-go/internal_gengo/well_known_types.go b/cmd/protoc-gen-go/internal_gengo/well_known_types.go index 696dddb9..47c4fa18 100644 --- a/cmd/protoc-gen-go/internal_gengo/well_known_types.go +++ b/cmd/protoc-gen-go/internal_gengo/well_known_types.go @@ -208,8 +208,7 @@ func genPackageKnownComment(f *fileInfo) protogen.Comments { "google.golang.org/protobuf/encoding/protojson" package ensures that they will be serialized as their JSON equivalent. - - Conversion to and from a Go interface + # Conversion to and from a Go interface The standard Go "encoding/json" package has functionality to serialize arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and @@ -222,8 +221,7 @@ func genPackageKnownComment(f *fileInfo) protogen.Comments { forms back as Value, Struct, and ListValue messages, use the NewStruct, NewList, and NewValue constructor functions. - - Example usage + # Example usage Consider the following example JSON object: @@ -282,7 +280,6 @@ func genPackageKnownComment(f *fileInfo) protogen.Comments { ... // handle error } ... // make use of m as a *structpb.Value - ` case genid.File_google_protobuf_field_mask_proto: return ` Package fieldmaskpb contains generated types for ` + genid.File_google_protobuf_field_mask_proto + `. @@ -656,8 +653,9 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message g.P("// AsMap converts x to a general-purpose Go map.") g.P("// The map values are converted by calling Value.AsInterface.") g.P("func (x *Struct) AsMap() map[string]interface{} {") - g.P(" vs := make(map[string]interface{})") - g.P(" for k, v := range x.GetFields() {") + g.P(" f := x.GetFields()") + g.P(" vs := make(map[string]interface{}, len(f))") + g.P(" for k, v := range f {") g.P(" vs[k] = v.AsInterface()") g.P(" }") g.P(" return vs") @@ -693,8 +691,9 @@ func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *message g.P("// AsSlice converts x to a general-purpose Go slice.") g.P("// The slice elements are converted by calling Value.AsInterface.") g.P("func (x *ListValue) AsSlice() []interface{} {") - g.P(" vs := make([]interface{}, len(x.GetValues()))") - g.P(" for i, v := range x.GetValues() {") + g.P(" vals := x.GetValues()") + g.P(" vs := make([]interface{}, len(vals))") + g.P(" for i, v := range vals {") g.P(" vs[i] = v.AsInterface()") g.P(" }") g.P(" return vs") diff --git a/types/known/structpb/struct.pb.go b/types/known/structpb/struct.pb.go index 882b0af6..89bdf572 100644 --- a/types/known/structpb/struct.pb.go +++ b/types/known/structpb/struct.pb.go @@ -44,8 +44,7 @@ // "google.golang.org/protobuf/encoding/protojson" package // ensures that they will be serialized as their JSON equivalent. // -// -// Conversion to and from a Go interface +// # Conversion to and from a Go interface // // The standard Go "encoding/json" package has functionality to serialize // arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and @@ -58,8 +57,7 @@ // forms back as Value, Struct, and ListValue messages, use the NewStruct, // NewList, and NewValue constructor functions. // -// -// Example usage +// # Example usage // // Consider the following example JSON object: // @@ -118,7 +116,6 @@ // ... // handle error // } // ... // make use of m as a *structpb.Value -// package structpb import ( @@ -218,8 +215,9 @@ func NewStruct(v map[string]interface{}) (*Struct, error) { // AsMap converts x to a general-purpose Go map. // The map values are converted by calling Value.AsInterface. func (x *Struct) AsMap() map[string]interface{} { - vs := make(map[string]interface{}) - for k, v := range x.GetFields() { + f := x.GetFields() + vs := make(map[string]interface{}, len(f)) + for k, v := range f { vs[k] = v.AsInterface() } return vs @@ -596,8 +594,9 @@ func NewList(v []interface{}) (*ListValue, error) { // AsSlice converts x to a general-purpose Go slice. // The slice elements are converted by calling Value.AsInterface. func (x *ListValue) AsSlice() []interface{} { - vs := make([]interface{}, len(x.GetValues())) - for i, v := range x.GetValues() { + vals := x.GetValues() + vs := make([]interface{}, len(vals)) + for i, v := range vals { vs[i] = v.AsInterface() } return vs