Documentation
¶
Overview ¶
Package codegen provides code generation for dynamic SSZ types.
Index ¶
- Variables
- func ParseTags(tag string) ([]ssztypes.SszTypeHint, []ssztypes.SszSizeHint, []ssztypes.SszMaxSizeHint, ...)
- type CodeGenerator
- type CodeGeneratorFileOptions
- type CodeGeneratorOption
- func WithCreateDecoderFn() CodeGeneratorOption
- func WithCreateEncoderFn() CodeGeneratorOption
- func WithCreateLegacyFn() CodeGeneratorOption
- func WithExtendedTypes() CodeGeneratorOption
- func WithGoTypesType(t types.Type, typeOpts ...CodeGeneratorOption) CodeGeneratorOption
- func WithGoTypesViewTypes(viewTypes ...types.Type) CodeGeneratorOption
- func WithMaxSizeHints(hints []ssztypes.SszMaxSizeHint) CodeGeneratorOption
- func WithNoFastSsz() CodeGeneratorOption
- func WithNoHashTreeRoot() CodeGeneratorOption
- func WithNoMarshalSSZ() CodeGeneratorOption
- func WithNoSizeSSZ() CodeGeneratorOption
- func WithNoUnmarshalSSZ() CodeGeneratorOption
- func WithReflectType(t reflect.Type, typeOpts ...CodeGeneratorOption) CodeGeneratorOption
- func WithReflectViewTypes(viewTypes ...reflect.Type) CodeGeneratorOption
- func WithSizeHints(hints []ssztypes.SszSizeHint) CodeGeneratorOption
- func WithTypeHints(hints []ssztypes.SszTypeHint) CodeGeneratorOption
- func WithViewOnly() CodeGeneratorOption
- func WithoutDynamicExpressions() CodeGeneratorOption
- type CodeGeneratorOptions
- type CodeGeneratorTypeOption
- type CodeGeneratorTypeOptions
- type CodegenInfo
- type Parser
- type TypeImport
- type TypePrinter
- func (p *TypePrinter) AddAlias(path, alias string)
- func (p *TypePrinter) AddImport(path, alias string) string
- func (p *TypePrinter) Aliases() map[string]string
- func (p *TypePrinter) Imports() map[string]string
- func (p *TypePrinter) InnerTypeString(t *ssztypes.TypeDescriptor) string
- func (p *TypePrinter) TypeString(t *ssztypes.TypeDescriptor) string
- func (p *TypePrinter) TypeStringWithoutTracking(t *ssztypes.TypeDescriptor, viewType bool) string
- func (p *TypePrinter) ViewTypeString(t *ssztypes.TypeDescriptor, ensurePointer bool) string
Constants ¶
This section is empty.
Variables ¶
var BuildCommit = ""
BuildCommit is the git commit hash, set via ldflags at build time.
var BuildTime = ""
BuildTime is the build timestamp, set via ldflags at build time.
var Version = "1.3.0"
Version is the release version of the dynamic-ssz library.
Functions ¶
func ParseTags ¶ added in v1.3.0
func ParseTags(tag string) ([]ssztypes.SszTypeHint, []ssztypes.SszSizeHint, []ssztypes.SszMaxSizeHint, error)
ParseTags parses SSZ annotations from a string in struct tag format. This is a convenience re-export of ssztypes.ParseTags for backward compatibility with code that imports codegen.ParseTags.
Types ¶
type CodeGenerator ¶
type CodeGenerator struct {
// contains filtered or unexported fields
}
CodeGenerator manages batch generation of SSZ methods for multiple types across multiple files.
The CodeGenerator provides a high-level interface for generating SSZ encoding/decoding methods for Go types. It supports generating multiple files with different configurations, each containing optimized SSZ methods for specified types.
Key capabilities:
- Batch generation of multiple files with different type sets
- Per-file and per-type configuration options
- Automatic dependency analysis and import management
- Support for both reflection-based and compile-time type analysis
- Integration with dynamic-ssz specifications and size expressions
The generator uses a DynSsz instance for type analysis and descriptor creation, ensuring that generated code is compatible with the runtime library's type system.
Fields:
- files: Internal list of file generation requests
- dynSsz: DynSsz instance used for type analysis and descriptor generation
Typical workflow:
- Create generator with NewCodeGenerator()
- Add files with BuildFile()
- Generate code with Generate() or GenerateToMap()
func NewCodeGenerator ¶
func NewCodeGenerator(typeCache *ssztypes.TypeCache) *CodeGenerator
NewCodeGenerator creates a new code generator instance with the specified DynSsz configuration.
The code generator requires a DynSsz instance to perform type analysis and create type descriptors for the types being generated. The DynSsz instance's specification values and configuration directly influence the generated code.
Parameters:
- dynSsz: DynSsz instance for type analysis and descriptor creation. If nil, a default instance with no specifications will be created.
Returns:
- *CodeGenerator: A new code generator ready to accept file generation requests
Example:
// Create with Ethereum mainnet specifications
specs := map[string]any{
"SLOTS_PER_HISTORICAL_ROOT": uint64(8192),
"SYNC_COMMITTEE_SIZE": uint64(512),
}
dynSsz := dynssz.NewDynSsz(specs)
cg := NewCodeGenerator(dynSsz)
// Create with default configuration
cg := NewCodeGenerator(nil)
func (*CodeGenerator) BuildFile ¶
func (cg *CodeGenerator) BuildFile(fileName string, opts ...CodeGeneratorOption)
BuildFile adds a file generation request to the code generator.
This method configures a single output file with its associated types and generation options. The file will be generated when Generate() or GenerateToMap() is called. All types specified in the options must belong to the same Go package.
The method processes all provided options to build the final configuration for the file, including resolving type-specific options and validating type compatibility.
Parameters:
- fileName: The output file path for the generated code
- opts: Variable number of options controlling file generation behavior
Example:
cg.BuildFile("ethereum_types_generated.go",
WithReflectType(reflect.TypeOf((*BeaconBlock)(nil)).Elem()),
WithReflectType(reflect.TypeOf((*BeaconState)(nil)).Elem(),
WithNoHashTreeRoot(), // Skip hash tree root for this type only
),
WithCreateLegacyFn(), // Generate legacy fastssz methods
WithSizeHints(sizeHints), // Apply size constraints
)
func (*CodeGenerator) Generate ¶
func (cg *CodeGenerator) Generate() error
Generate processes all file generation requests and writes the results to disk.
This method is a convenience wrapper around GenerateToMap() that automatically writes all generated files to their specified paths. It handles directory creation as needed and ensures proper file permissions.
The method will create any necessary intermediate directories and write each generated file with standard Go source file permissions (0644).
Returns:
- error: An error if generation or file writing fails due to:
- Any errors from GenerateToMap()
- File system permission issues
- Directory creation failures
- File write failures
Example:
cg := NewCodeGenerator(dynSsz)
cg.BuildFile("./generated/types.go", WithReflectType(myType))
cg.BuildFile("./generated/helpers.go", WithReflectType(anotherType))
err := cg.Generate()
if err != nil {
log.Fatal("Failed to generate files:", err)
}
func (*CodeGenerator) GenerateToMap ¶
func (cg *CodeGenerator) GenerateToMap() (map[string]string, error)
GenerateToMap generates code for all requested files and returns the results as a map.
This method processes all file generation requests added via BuildFile() and produces the complete Go source code for each file. The returned map contains the file names as keys and the generated source code as values.
The generation process includes:
- Type analysis and descriptor creation for all specified types
- Dependency resolution and import management
- SSZ method generation (marshal, unmarshal, size, hash tree root)
- Go source code formatting and organization
- Cross-reference resolution for types that reference each other
Returns:
- map[string]string: Map of file names to their generated Go source code
- error: An error if generation fails due to:
- Type analysis errors
- Package path conflicts
- Invalid type configurations
- Code generation errors
Example:
cg := NewCodeGenerator(dynSsz)
cg.BuildFile("types.go", WithReflectType(myType))
cg.BuildFile("more_types.go", WithReflectType(anotherType))
files, err := cg.GenerateToMap()
if err != nil {
log.Fatal(err)
}
for fileName, code := range files {
fmt.Printf("Generated %s:\n%s\n", fileName, code)
}
func (*CodeGenerator) SetPackageName ¶ added in v1.1.1
func (cg *CodeGenerator) SetPackageName(packageName string)
SetPackageName sets the package name for the code generator.
This method sets the package name for the code generator.
Parameters:
- packageName: The package name to set
Returns:
- *CodeGenerator: The code generator instance
Example:
cg := NewCodeGenerator(dynSsz)
cg.SetPackageName("my_package")
cg.BuildFile("types.go", WithReflectType(reflect.TypeOf((*MyStruct)(nil)).Elem()))
cg.Generate()
type CodeGeneratorFileOptions ¶
type CodeGeneratorFileOptions struct {
Package string
PackageName string
Types []*CodeGeneratorTypeOptions
}
CodeGeneratorFileOptions contains the configuration for generating a complete Go source file.
This structure represents all the information needed to generate a single Go file containing SSZ methods for multiple types. It includes package information and the complete list of types to be included in the file with their individual configurations.
File Structure:
- Package: The Go package path for the generated file
- Types: All types to include in the file with their resolved configurations
The generator ensures all types belong to the same package and handles import management, method generation, and proper Go source code formatting for the entire file.
type CodeGeneratorOption ¶
type CodeGeneratorOption func(*CodeGeneratorOptions)
CodeGeneratorOption is a functional option for configuring code generation behavior.
This type follows the functional options pattern, allowing callers to customize various aspects of the code generation process through composable option functions. Options can control which methods are generated, performance optimizations, and compatibility settings.
Example usage:
cg := NewCodeGenerator(dynSsz)
cg.BuildFile("generated.go",
WithNoMarshalSSZ(), // Skip marshal method generation
WithCreateLegacyFn(), // Generate legacy fastssz methods
WithoutDynamicExpressions(), // Use static sizes only
)
func WithCreateDecoderFn ¶ added in v1.2.0
func WithCreateDecoderFn() CodeGeneratorOption
WithCreateDecoderFn creates an option to generate decoder functions.
When this option is enabled, the generator will generate decoder functions for the types.
Returns:
- CodeGeneratorOption: A functional option that enables decoder function generation
func WithCreateEncoderFn ¶ added in v1.2.0
func WithCreateEncoderFn() CodeGeneratorOption
WithCreateEncoderFn creates an option to generate encoder functions.
When this option is enabled, the generator will generate encoder functions for the types.
Returns:
- CodeGeneratorOption: A functional option that enables encoder function generation
func WithCreateLegacyFn ¶
func WithCreateLegacyFn() CodeGeneratorOption
WithCreateLegacyFn creates an option to generate legacy fastssz-compatible methods.
When this option is enabled, the generator creates additional methods that match the fastssz library interface, using a global DynSsz instance for compatibility. These methods include:
- MarshalSSZ() ([]byte, error)
- UnmarshalSSZ([]byte) error
- SizeSSZ() int
- HashTreeRoot() ([32]byte, error)
This option is essential for:
- Drop-in replacement for fastssz-generated code
- Gradual migration from fastssz to dynamic-ssz
- Interoperability with existing codebases expecting fastssz interfaces
- Maintaining backward compatibility in public APIs
The legacy methods delegate to the dynamic methods using the global DynSsz instance, so they inherit all dynamic sizing and expression capabilities.
Returns:
- CodeGeneratorOption: A functional option that enables legacy method generation
func WithExtendedTypes ¶ added in v1.2.2
func WithExtendedTypes() CodeGeneratorOption
WithExtendedTypes creates an option to generate code with extended types.
When this option is enabled, the generator will generate code with extended types.
Returns:
- CodeGeneratorOption: A functional option that enables extended type generation
func WithGoTypesType ¶
func WithGoTypesType(t types.Type, typeOpts ...CodeGeneratorOption) CodeGeneratorOption
WithGoTypesType creates an option to include a specific type using compile-time type analysis.
This function adds a type to the generation list using Go's types package for compile-time type analysis. This approach is more powerful than reflection as it can analyze types that may not be available at runtime and provides richer type information for complex scenarios.
This method is typically used in code analysis tools, compilers, or advanced code generation scenarios where you're working with the Go AST or type checker.
Parameters:
- t: The types.Type to include in code generation (from go/types package)
- typeOpts: Optional type-specific generation options that override base settings
Returns:
- CodeGeneratorOption: A functional option that adds the type to the generation list
Example:
// In a compiler or analysis tool context
var structType *types.Named = ... // obtained from type analysis
WithGoTypesType(structType,
WithCreateLegacyFn(),
WithoutDynamicExpressions(),
)
func WithGoTypesViewTypes ¶ added in v1.3.0
func WithGoTypesViewTypes(viewTypes ...types.Type) CodeGeneratorOption
WithGoTypesViewTypes creates an option to specify view types for data+views mode.
This option specifies view types that share the same SSZ schema as the data type. When code is generated, both regular data methods and view-compatible methods will be created, allowing the data type's methods to work with these view types.
Parameters:
- viewTypes: View types that share the same SSZ schema as the data type
Returns:
- CodeGeneratorOption: A functional option that sets view types
Example:
WithGoTypesType(dataType,
WithGoTypesViewTypes(viewType1, viewType2),
)
func WithMaxSizeHints ¶
func WithMaxSizeHints(hints []ssztypes.SszMaxSizeHint) CodeGeneratorOption
WithMaxSizeHints creates an option to provide maximum size constraints for variable-length types.
Maximum size hints define upper bounds for variable-length types like slices and lists. These constraints are crucial for:
- Memory allocation optimization
- Security bounds checking
- SSZ encoding validation
- Buffer pre-allocation in performance-critical code
The hints help generate efficient code that can pre-allocate appropriate buffer sizes and validate data doesn't exceed specified limits during encoding/decoding.
Parameters:
- hints: Array of maximum size hints, typically corresponding to nested type levels
Returns:
- CodeGeneratorOption: A functional option that applies the provided maximum size hints
Example:
WithMaxSizeHints([]dynssz.SszMaxSizeHint{
{Size: 1048576, Expr: "MAX_VALIDATORS_PER_COMMITTEE"},
})
func WithNoFastSsz ¶ added in v1.1.1
func WithNoFastSsz() CodeGeneratorOption
WithNoFastSsz creates an option to skip generating fast ssz generated methods.
When this option is enabled, the generator will not use any fast ssz generated methods for static types.
Returns:
- CodeGeneratorOption: A functional option that disables fast ssz generated method generation
func WithNoHashTreeRoot ¶
func WithNoHashTreeRoot() CodeGeneratorOption
WithNoHashTreeRoot creates an option to skip generating HashTreeRoot and HashTreeRootDyn methods.
When this option is applied, the code generator will not produce hash tree root calculation methods for the target types. This is useful when:
- Hash tree roots are not needed for the application
- Custom hashing logic is implemented elsewhere
- Optimizing for code size when cryptographic commitments aren't required
Note that hash tree roots are essential for many blockchain and cryptographic applications, particularly in Ethereum consensus where they're used for Merkle proofs and state roots.
Returns:
- CodeGeneratorOption: A functional option that disables hash tree root method generation
func WithNoMarshalSSZ ¶
func WithNoMarshalSSZ() CodeGeneratorOption
WithNoMarshalSSZ creates an option to skip generating MarshalSSZTo and MarshalSSZDyn methods.
When this option is applied, the code generator will not produce any marshaling methods for the target types. This is useful when:
- Types only need to be deserialized (read-only scenarios)
- Custom marshaling logic is implemented elsewhere
- Reducing generated code size for specific use cases
Note that skipping marshal methods may limit interoperability with some SSZ libraries that expect the full method interface to be present.
Returns:
- CodeGeneratorOption: A functional option that disables marshal method generation
func WithNoSizeSSZ ¶
func WithNoSizeSSZ() CodeGeneratorOption
WithNoSizeSSZ creates an option to skip generating SizeSSZ and SizeSSZDyn methods.
When this option is applied, the code generator will not produce size calculation methods for the target types. This is useful when:
- Size calculation is not needed for the application
- Custom size calculation logic is implemented elsewhere
- Optimizing for code size in constrained environments
Note that many SSZ operations benefit from accurate size pre-calculation for buffer allocation, so this option should be used carefully.
Returns:
- CodeGeneratorOption: A functional option that disables size method generation
func WithNoUnmarshalSSZ ¶
func WithNoUnmarshalSSZ() CodeGeneratorOption
WithNoUnmarshalSSZ creates an option to skip generating UnmarshalSSZ and UnmarshalSSZDyn methods.
When this option is applied, the code generator will not produce any unmarshaling methods for the target types. This is useful when:
- Types are only created programmatically (write-only scenarios)
- Custom unmarshaling logic is implemented elsewhere
- Reducing generated code size for specific use cases
Note that skipping unmarshal methods may limit interoperability with some SSZ libraries that expect the full method interface to be present.
Returns:
- CodeGeneratorOption: A functional option that disables unmarshal method generation
func WithReflectType ¶
func WithReflectType(t reflect.Type, typeOpts ...CodeGeneratorOption) CodeGeneratorOption
WithReflectType creates an option to include a specific type using runtime reflection.
This function adds a type to the generation list using Go's reflection system to analyze the type structure. It's the most common way to specify types for generation when you have access to the actual Go types at runtime.
The function accepts additional type-specific options that will be applied only to this type, allowing fine-grained control over generation behavior per type.
Parameters:
- t: The reflect.Type to include in code generation (typically obtained via reflect.TypeOf)
- typeOpts: Optional type-specific generation options that override base settings
Returns:
- CodeGeneratorOption: A functional option that adds the type to the generation list
Example:
// Add a type with default options
WithReflectType(reflect.TypeOf((*MyStruct)(nil)).Elem()),
// Add a type with specific options
WithReflectType(reflect.TypeOf((*AnotherStruct)(nil)).Elem(),
WithNoHashTreeRoot(), // Skip hash tree root for this type only
WithCreateLegacyFn(), // But include legacy methods
),
func WithReflectViewTypes ¶ added in v1.3.0
func WithReflectViewTypes(viewTypes ...reflect.Type) CodeGeneratorOption
WithReflectViewTypes creates an option to specify view types for data+views mode.
This option specifies view types that share the same SSZ schema as the data type. When code is generated, both regular data methods and view-compatible methods will be created, allowing the data type's methods to work with these view types.
Parameters:
- viewTypes: View types that share the same SSZ schema as the data type
Returns:
- CodeGeneratorOption: A functional option that sets view types
Example:
WithReflectType(dataType,
WithReflectViewTypes(viewType1, viewType2),
)
func WithSizeHints ¶
func WithSizeHints(hints []ssztypes.SszSizeHint) CodeGeneratorOption
WithSizeHints creates an option to provide size constraints for dynamic types.
Size hints guide the code generator in handling types with variable or dynamic sizes. They can specify exact sizes, dynamic sizing expressions, or size calculation formulas that reference runtime specification values.
Common use cases:
- Fixed-size arrays where size depends on configuration: []Item with size "SLOTS_PER_EPOCH"
- Variable-size containers with known constraints
- Performance optimization by pre-calculating buffer sizes
Parameters:
- hints: Array of size hints, typically corresponding to nested type levels
Returns:
- CodeGeneratorOption: A functional option that applies the provided size hints
Example:
WithSizeHints([]dynssz.SszSizeHint{
{Size: 8192, Expr: "SLOTS_PER_HISTORICAL_ROOT"},
})
func WithTypeHints ¶
func WithTypeHints(hints []ssztypes.SszTypeHint) CodeGeneratorOption
WithTypeHints creates an option to provide explicit SSZ type mappings for ambiguous Go types.
Type hints resolve ambiguity when Go types can be mapped to multiple SSZ types. This is particularly important for:
- Generic types that could be containers, lists, or vectors
- Interface types that need concrete SSZ representations
- Custom types that implement multiple SSZ-compatible interfaces
- Ensuring consistent type interpretation across different contexts
The hints allow precise control over how the generator interprets and encodes complex type hierarchies, ensuring compatibility with dynamic expressions and runtime specifications.
Parameters:
- hints: Array of type hints mapping Go types to specific SSZ type interpretations
Returns:
- CodeGeneratorOption: A functional option that applies the provided type hints
Example:
WithTypeHints([]dynssz.SszTypeHint{
{Type: dynssz.SszListType}, // Force slice to be treated as list not vector
{Type: dynssz.SszContainerType}, // Force struct to be treated as container
})
func WithViewOnly ¶ added in v1.3.0
func WithViewOnly() CodeGeneratorOption
WithViewOnly creates an option to generate only view methods, not data methods.
When this option is set, the generator will only produce view-compatible methods (like MarshalSSZToView, UnmarshalSSZView, etc.) and skip generating standard data methods (MarshalSSZTo, UnmarshalSSZ, etc.).
This is useful when you have a type that is only used as a view for another data type and doesn't need its own data serialization methods.
Returns:
- CodeGeneratorOption: A functional option that enables view-only mode
Example:
WithGoTypesType(viewType,
WithViewOnly(),
WithGoTypesViewTypes(otherViewType), // additional views
)
func WithoutDynamicExpressions ¶
func WithoutDynamicExpressions() CodeGeneratorOption
WithoutDynamicExpressions creates an option to generate static-only code that ignores dynamic expressions.
When this option is enabled, the generator produces highly optimized code that uses only static, compile-time known sizes and completely ignores any dynamic size expressions. This results in:
- Maximum performance characteristics for the default/known preset
- Smaller generated code size
- No runtime expression evaluation overhead
- Compile-time size validation
Trade-offs:
- Loss of flexibility for different presets/specifications
- Cannot handle runtime size variations
- Falls back to slower reflection-based methods for dynamic cases
- Not compatible with types that require dynamic expression evaluation
This option is ideal for production deployments where:
- The specification preset is known at compile time
- Maximum performance is prioritized over flexibility
- Code size optimization is important
Returns:
- CodeGeneratorOption: A functional option that enables static-only code generation
type CodeGeneratorOptions ¶
type CodeGeneratorOptions struct {
NoMarshalSSZ bool
NoUnmarshalSSZ bool
NoSizeSSZ bool
NoHashTreeRoot bool
CreateLegacyFn bool
CreateEncoderFn bool
CreateDecoderFn bool
WithoutDynamicExpressions bool
NoFastSsz bool
ExtendedTypes bool
SizeHints []ssztypes.SszSizeHint
MaxSizeHints []ssztypes.SszMaxSizeHint
TypeHints []ssztypes.SszTypeHint
Types []CodeGeneratorTypeOption
// View support options (type-specific)
ViewGoTypesTypes []types.Type // View types for data+views mode (compile-time)
ViewReflectTypes []reflect.Type // View types for data+views mode (runtime)
ViewOnly bool // Only generate view methods, not data methods
}
CodeGeneratorOptions contains all configuration settings for code generation.
This structure controls every aspect of the code generation process, from which methods to generate to performance optimizations and compatibility modes. It serves as the central configuration hub for customizing generated SSZ code to meet specific requirements and constraints.
Method Generation Controls:
- NoMarshalSSZ: Skip generating MarshalSSZTo and MarshalSSZDyn methods
- NoUnmarshalSSZ: Skip generating UnmarshalSSZ and UnmarshalSSZDyn methods
- NoSizeSSZ: Skip generating SizeSSZ and SizeSSZDyn methods
- NoHashTreeRoot: Skip generating HashTreeRoot and HashTreeRootDyn methods
Compatibility and Performance Options:
- CreateLegacyFn: Generate legacy fastssz-compatible methods (MarshalSSZ, etc.)
- WithoutDynamicExpressions: Generate static-only code, ignoring dynamic expressions
- NoFastSsz: Disable use of fastssz optimizations in generated code
Type Configuration:
- SizeHints: Static and dynamic size constraints for types
- MaxSizeHints: Maximum size limits for variable-length types
- TypeHints: Explicit SSZ type mappings for ambiguous Go types
- Types: Specific types to include in generation with per-type options
type CodeGeneratorTypeOption ¶
type CodeGeneratorTypeOption struct {
ReflectType reflect.Type
GoTypesType types.Type
Opts []CodeGeneratorOption
}
CodeGeneratorTypeOption specifies a type to include in code generation with its specific options.
This structure allows fine-grained control over individual types within a generation request. Each type can have its own set of generation options that override or extend the base configuration. This enables scenarios like generating different method sets for different types within the same output file.
Type Specification (exactly one must be provided):
- ReflectType: Go reflection-based type representation (runtime type)
- GoTypesType: Go types package representation (compile-time type analysis)
Configuration:
- Opts: Type-specific options that will be applied in addition to base options
View support is configured via options:
- WithGoTypesViewTypes() / WithReflectViewTypes(): Specify view types for data+views mode
- WithViewOnly(): Only generate view methods, not data methods
Example:
// Generate type with view support
WithReflectType(reflect.TypeOf((*MyStruct)(nil)).Elem(),
WithReflectViewTypes(reflect.TypeOf((*MyView)(nil)).Elem()),
),
// Generate view-only type
WithReflectType(reflect.TypeOf((*ViewType)(nil)).Elem(),
WithViewOnly(),
WithReflectViewTypes(reflect.TypeOf((*OtherView)(nil)).Elem()),
),
type CodeGeneratorTypeOptions ¶
type CodeGeneratorTypeOptions struct {
ReflectType reflect.Type
GoTypesType types.Type
TypeName string
Options CodeGeneratorOptions
Descriptor *ssztypes.TypeDescriptor
// View types for data+views mode
ViewGoTypesTypes []types.Type
ViewReflectTypes []reflect.Type
ViewDescriptors []*ssztypes.TypeDescriptor
// IsViewOnly marks this type as view-only (only generates view methods)
IsViewOnly bool
}
CodeGeneratorTypeOptions contains the resolved configuration for a specific type during generation.
This structure represents the final, processed configuration for a type after all options have been applied and type analysis has been completed. It serves as the authoritative source of information about how a type should be generated, including its resolved type descriptor and effective generation options.
Type Information:
- ReflectType: Runtime reflection type representation
- GoTypesType: Compile-time type analysis representation
- TypeName: Resolved type name for code generation
View Support:
- ViewGoTypesTypes: Resolved view types for data+views mode
- ViewReflectTypes: Resolved view types for data+views mode
- IsViewOnly: Whether this is a view-only type
- SchemaDescriptor: Schema type descriptor for view-only mode
Generation Configuration:
- Options: Final resolved options after applying base and type-specific settings
- Descriptor: Analyzed SSZ type descriptor containing encoding/decoding metadata
type CodegenInfo ¶
CodegenInfo contains type information specific to code generation from go/types analysis.
This structure bridges the gap between compile-time type analysis (using go/types) and runtime code generation. It stores type information that was obtained through static analysis rather than runtime reflection, enabling more sophisticated code generation scenarios.
Fields:
- Type: The types.Type from go/types package representing the analyzed type
- SchemaType: The types.Type representing the schema structure (may differ from Type for view descriptors)
This information is embedded in TypeDescriptor.CodegenInfo to provide access to compile-time type information during code generation.
type Parser ¶
type Parser struct {
CompatFlags map[string]ssztypes.SszCompatFlag
ExtendedTypes bool
// contains filtered or unexported fields
}
Parser provides compile-time type analysis for SSZ code generation.
The Parser analyzes Go types using the go/types package to create TypeDescriptors suitable for code generation. Unlike runtime reflection, this approach can analyze types that may not be available at runtime and provides richer type information for complex code generation scenarios.
Key capabilities:
- Compile-time type analysis using go/types
- SSZ type inference and validation
- Struct tag parsing for SSZ annotations
- Interface compatibility checking
- Type descriptor caching for performance
The parser handles all SSZ-compatible types including basic types, containers, vectors, lists, and custom types like unions and type wrappers.
Fields:
- cache: Type descriptor cache to avoid recomputing analysis for the same types
func NewParser ¶
func NewParser() *Parser
NewParser creates a new compile-time type parser for code generation.
The parser is initialized with an empty cache and is ready to analyze types using the go/types package. The parser can be reused across multiple type analysis operations to benefit from caching.
Returns:
- *Parser: A new parser instance ready for type analysis
Example:
parser := NewParser()
desc, err := parser.GetTypeDescriptor(myGoType, nil, nil, nil)
if err != nil {
log.Fatal("Type analysis failed:", err)
}
func (*Parser) GetTypeDescriptor ¶
func (p *Parser) GetTypeDescriptor(typ types.Type, typeHints []ssztypes.SszTypeHint, sizeHints []ssztypes.SszSizeHint, maxSizeHints []ssztypes.SszMaxSizeHint) (*ssztypes.TypeDescriptor, error)
GetTypeDescriptor analyzes a Go type and creates an SSZ type descriptor for code generation.
This method is the main entry point for type analysis. It examines the provided go/types.Type and creates a comprehensive TypeDescriptor containing all information needed for SSZ code generation, including size calculations, encoding strategies, and interface compatibility.
The analysis process includes:
- Type structure examination and validation
- SSZ type inference and mapping
- Size and constraint analysis from hints
- Interface compatibility checking
- Nested type analysis for containers and collections
Parameters:
- typ: The go/types.Type to analyze
- typeHints: Optional hints for explicit SSZ type mapping
- sizeHints: Optional size constraints and expressions
- maxSizeHints: Optional maximum size limits for variable-length types
Returns:
- *ssztypes.TypeDescriptor: Complete type descriptor for code generation
- error: An error if the type is incompatible with SSZ or analysis fails
Example:
parser := NewParser()
typeHints := []ssztypes.SszTypeHint{{Type: ssztypes.SszListType}}
sizeHints := []ssztypes.SszSizeHint{{Size: 1024}}
desc, err := parser.GetTypeDescriptor(structType, typeHints, sizeHints, nil)
if err != nil {
return fmt.Errorf("failed to analyze type: %w", err)
}
func (*Parser) GetTypeDescriptorWithSchema ¶ added in v1.3.0
func (p *Parser) GetTypeDescriptorWithSchema(dataType, schemaType types.Type, typeHints []ssztypes.SszTypeHint, sizeHints []ssztypes.SszSizeHint, maxSizeHints []ssztypes.SszMaxSizeHint) (*ssztypes.TypeDescriptor, error)
GetTypeDescriptorWithSchema analyzes Go types and creates an SSZ type descriptor with separate schema and data types.
This method supports fork-dependent SSZ schemas (view descriptors) where the schema type defines the SSZ layout while the data type holds the actual data. This allows different SSZ serializations of the same data based on the schema provided.
When dataType == schemaType, this behaves identically to GetTypeDescriptor. When they differ, the descriptor is built using schema's field definitions (names, tags, order) but code generation targets the data type's fields.
Parameters:
- dataType: The types.Type where actual data lives (runtime type)
- schemaType: The types.Type that defines SSZ layout (field order, tags, limits)
- typeHints: Optional hints for explicit SSZ type mapping
- sizeHints: Optional size constraints and expressions
- maxSizeHints: Optional maximum size limits for variable-length types
Returns:
- *ssztypes.TypeDescriptor: Complete type descriptor for code generation
- error: An error if the type is incompatible with SSZ or analysis fails
type TypeImport ¶
TypeImport represents an import declaration for generated code files.
This structure is used during code generation to track and organize import statements that need to be included in the generated Go files. It pairs import paths with their corresponding aliases to avoid naming conflicts and provide clean, readable generated code.
Fields:
- Alias: The alias name for the import (empty string means no alias)
- Path: The full import path (e.g., "github.com/pkg/errors")
type TypePrinter ¶
type TypePrinter struct {
CurrentPkg string
UseRune bool
// contains filtered or unexported fields
}
TypePrinter manages type name formatting and import tracking for code generation.
The TypePrinter provides intelligent type name formatting that handles package qualification, import management, and alias generation. It ensures that generated code has clean, readable type names while avoiding import conflicts.
Key capabilities:
- Automatic package qualification for types from other packages
- Import path tracking and alias generation
- Conflict resolution for import aliases
- Support for both reflection and go/types type representations
- Generic type name formatting with proper package path handling
Fields:
- CurrentPkg: The package path of the code being generated (types from this package are unqualified)
- imports: Map of import paths to their assigned aliases
- aliases: Map of import paths to their preferred aliases
- UseRune: Whether to prefer "rune" over "int32" in type names
func NewTypePrinter ¶
func NewTypePrinter(currentPkg string) *TypePrinter
NewTypePrinter creates a new type printer for the specified package.
The type printer is configured to generate type names relative to the specified current package. Types from the current package will be unqualified, while types from other packages will be properly qualified with import aliases.
Parameters:
- currentPkg: The Go package path of the code being generated
Returns:
- *TypePrinter: A new type printer ready for type formatting and import tracking
Example:
printer := NewTypePrinter("github.com/example/mypackage")
typeName := printer.TypeString(myTypeDescriptor) // Will qualify external types
func (*TypePrinter) AddAlias ¶
func (p *TypePrinter) AddAlias(path, alias string)
AddAlias sets a preferred alias for an import path.
This method establishes a preferred alias for a specific import path. When generating import statements, these preferred aliases will be used instead of automatically generated ones, providing consistent and predictable import formatting.
Parameters:
- path: The import path to set an alias for
- alias: The preferred alias to use for this import path
Example:
printer.AddAlias("github.com/pk910/dynamic-ssz", "dynssz")
// All references to dynamic-ssz types will use "dynssz" as the package qualifier
func (*TypePrinter) AddImport ¶
func (p *TypePrinter) AddImport(path, alias string) string
AddImport registers an import path with a preferred alias and returns the assigned alias.
This method adds an import path to the printer's import tracking system. If the path is already registered, it returns the existing alias. If the preferred alias conflicts with an existing import, it generates a unique alternative by appending numbers.
Parameters:
- path: The import path to register (e.g., "github.com/pkg/errors")
- alias: The preferred alias for the import (e.g., "errors")
Returns:
- string: The actual alias assigned to the import (may differ from preferred if conflicts occur)
Example:
alias := printer.AddImport("github.com/pkg/errors", "errors")
// alias == "errors" if no conflict, or "errors1", "errors2", etc. if conflicts exist
func (*TypePrinter) Aliases ¶
func (p *TypePrinter) Aliases() map[string]string
Aliases returns the map of import paths to their preferred aliases.
This method provides access to the preferred alias mappings that were set via AddAlias(). These aliases take precedence over automatically generated aliases when formatting import statements.
Returns:
- map[string]string: Map of import paths to their preferred aliases
func (*TypePrinter) Imports ¶
func (p *TypePrinter) Imports() map[string]string
Imports returns the map of import paths to their assigned aliases.
This method provides access to all import paths that have been registered during type formatting operations. The returned map can be used to generate the import section of a Go source file.
Returns:
- map[string]string: Map of import paths to their assigned aliases
func (*TypePrinter) InnerTypeString ¶
func (p *TypePrinter) InnerTypeString(t *ssztypes.TypeDescriptor) string
InnerTypeString returns the qualified string representation of the inner (dereferenced) type.
This method is similar to TypeString but automatically dereferences pointer types to get the underlying type. It's particularly useful when generating code that needs to work with the actual value type rather than pointer types.
For pointer types, this returns the element type. For non-pointer types, this behaves identically to TypeString.
Parameters:
- t: The TypeDescriptor containing type information for formatting
Returns:
- string: The qualified Go type string of the inner/dereferenced type
Example:
// For *MyStruct innerType := printer.InnerTypeString(descriptor) // Result: "MyStruct" (without the pointer)
func (*TypePrinter) TypeString ¶
func (p *TypePrinter) TypeString(t *ssztypes.TypeDescriptor) string
TypeString returns the qualified string representation of a type descriptor and tracks import usage.
This method generates the appropriate Go type string for a TypeDescriptor, handling package qualification and import tracking automatically. It works with both types analyzed via go/types (compile-time) and reflection (runtime).
The method automatically:
- Qualifies types from other packages with appropriate import aliases
- Tracks import usage for later import statement generation
- Handles generic types with complex package path references
- Prefers compile-time type information when available
Parameters:
- t: The TypeDescriptor containing type information for formatting
Returns:
- string: The qualified Go type string suitable for code generation
Example:
typeName := printer.TypeString(descriptor) // Result: "phase0.BeaconBlock" or "*MyStruct" depending on the type
func (*TypePrinter) TypeStringWithoutTracking ¶
func (p *TypePrinter) TypeStringWithoutTracking(t *ssztypes.TypeDescriptor, viewType bool) string
TypeStringWithoutTracking returns the type string representation without tracking import usage.
This method generates type strings without adding imports to the tracking system. It's useful for scenarios where you need type names for analysis or comparison but don't want to affect the import management (e.g., during validation or debugging).
The generated string will still be properly qualified but won't register any imports for later code generation.
Parameters:
- t: The TypeDescriptor containing type information for formatting
Returns:
- string: The qualified Go type string without import tracking side effects
func (*TypePrinter) ViewTypeString ¶ added in v1.3.0
func (p *TypePrinter) ViewTypeString(t *ssztypes.TypeDescriptor, ensurePointer bool) string
ViewTypeString returns the qualified string representation of a view type descriptor and tracks import usage.
This method generates the appropriate Go type string for a view TypeDescriptor, handling package qualification and import tracking automatically.
Parameters:
- t: The view TypeDescriptor containing type information for formatting
Returns:
- string: The qualified Go type string suitable for code generation
Example:
typeName := printer.TypeString(descriptor) // Result: "phase0.BeaconBlock" or "*MyStruct" depending on the type