src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

schema_ext.go (1252B)


      1 package smithy
      2 
      3 import (
      4 	"sync/atomic"
      5 	"unsafe"
      6 )
      7 
      8 // ExtensionID identifies a schema extension slot. Each codec family
      9 // (JSON, CBOR, etc.) uses a distinct slot to cache precomputed data.
     10 type ExtensionID int
     11 
     12 const numExtensionSlots = 5
     13 
     14 const (
     15 	ExtJSON        ExtensionID = iota // transport/http/protocol/internal/json
     16 	ExtCBOR                           // transport/http/protocol/internal/cbor
     17 	ExtXML                            // transport/http/protocol/internal/xml
     18 	ExtQuery                          // transport/http/protocol/internal/query
     19 	ExtHTTPBinding                    // transport/http/protocol/internal/httpbinding
     20 )
     21 
     22 // SchemaExtension retrieves or lazily computes the extension for the given
     23 // slot. build is called on first access for a schema and the result is cached.
     24 // The build function must return a pointer to an immutable value.
     25 func SchemaExtension[T any](s *Schema, id ExtensionID, build func(*Schema) *T) *T {
     26 	p := atomic.LoadPointer(&s.ext[id])
     27 	if p != nil {
     28 		return (*T)(p)
     29 	}
     30 	return computeSchemaExtension(s, id, build)
     31 }
     32 
     33 //go:noinline
     34 func computeSchemaExtension[T any](s *Schema, id ExtensionID, build func(*Schema) *T) *T {
     35 	v := build(s)
     36 	atomic.StorePointer(&s.ext[id], unsafe.Pointer(v))
     37 	return v
     38 }