@@ -15,11 +15,8 @@ import (
1515 "io"
1616 "mime/multipart"
1717 "net/url"
18- "os"
1918 "path"
20- "reflect"
2119 "strings"
22- "time"
2320
2421 "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
2522 "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
@@ -105,9 +102,6 @@ func MarshalAsByteArray(req *policy.Request, v []byte, format Base64Encoding) er
105102
106103// MarshalAsJSON calls json.Marshal() to get the JSON encoding of v then calls SetBody.
107104func MarshalAsJSON (req * policy.Request , v interface {}) error {
108- if omit := os .Getenv ("AZURE_SDK_GO_OMIT_READONLY" ); omit == "true" {
109- v = cloneWithoutReadOnlyFields (v )
110- }
111105 b , err := json .Marshal (v )
112106 if err != nil {
113107 return fmt .Errorf ("error marshalling type %T: %s" , v , err )
@@ -181,81 +175,3 @@ func SkipBodyDownload(req *policy.Request) {
181175
182176// CtxAPINameKey is used as a context key for adding/retrieving the API name.
183177type CtxAPINameKey = shared.CtxAPINameKey
184-
185- // returns a clone of the object graph pointed to by v, omitting values of all read-only
186- // fields. if there are no read-only fields in the object graph, no clone is created.
187- func cloneWithoutReadOnlyFields (v interface {}) interface {} {
188- val := reflect .Indirect (reflect .ValueOf (v ))
189- if val .Kind () != reflect .Struct {
190- // not a struct, skip
191- return v
192- }
193- // first walk the graph to find any R/O fields.
194- // if there aren't any, skip cloning the graph.
195- if ! recursiveFindReadOnlyField (val ) {
196- return v
197- }
198- return recursiveCloneWithoutReadOnlyFields (val )
199- }
200-
201- // returns true if any field in the object graph of val contains the `azure:"ro"` tag value
202- func recursiveFindReadOnlyField (val reflect.Value ) bool {
203- t := val .Type ()
204- // iterate over the fields, looking for the "azure" tag.
205- for i := 0 ; i < t .NumField (); i ++ {
206- field := t .Field (i )
207- aztag := field .Tag .Get ("azure" )
208- if azureTagIsReadOnly (aztag ) {
209- return true
210- } else if reflect .Indirect (val .Field (i )).Kind () == reflect .Struct && recursiveFindReadOnlyField (reflect .Indirect (val .Field (i ))) {
211- return true
212- }
213- }
214- return false
215- }
216-
217- // clones the object graph of val. all non-R/O properties are copied to the clone
218- func recursiveCloneWithoutReadOnlyFields (val reflect.Value ) interface {} {
219- t := val .Type ()
220- clone := reflect .New (t )
221- // iterate over the fields, looking for the "azure" tag.
222- for i := 0 ; i < t .NumField (); i ++ {
223- field := t .Field (i )
224- aztag := field .Tag .Get ("azure" )
225- if azureTagIsReadOnly (aztag ) {
226- // omit from payload
227- continue
228- }
229- // clone field will receive the same value as the source field...
230- value := val .Field (i )
231- v := reflect .Indirect (value )
232- if v .IsValid () && v .Type () != reflect .TypeOf (time.Time {}) && v .Kind () == reflect .Struct {
233- // ...unless the source value is a struct, in which case we recurse to clone that struct.
234- // (We can't recursively clone time.Time because it contains unexported fields.)
235- c := recursiveCloneWithoutReadOnlyFields (v )
236- if field .Anonymous {
237- // NOTE: this does not handle the case of embedded fields of unexported struct types.
238- // this should be ok as we don't generate any code like this at present
239- value = reflect .Indirect (reflect .ValueOf (c ))
240- } else {
241- value = reflect .ValueOf (c )
242- }
243- }
244- reflect .Indirect (clone ).Field (i ).Set (value )
245- }
246- return clone .Interface ()
247- }
248-
249- // returns true if the "azure" tag contains the option "ro"
250- func azureTagIsReadOnly (tag string ) bool {
251- if tag == "" {
252- return false
253- }
254- parts := strings .Split (tag , "," )
255- for _ , part := range parts {
256- if part == "ro" {
257- return true
258- }
259- }
260- return false
261- }
0 commit comments