Skip to content

Commit

Permalink
fix generation
Browse files Browse the repository at this point in the history
  • Loading branch information
lumtis committed Oct 9, 2024
1 parent de4ec95 commit 8ebbb0b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 40 deletions.
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,20 @@ fmt:
@./scripts/fmt.sh


# Variables
GENERATOR_DIR := go-idl/generator
IDL_FILE := target/idl/gateway.json
OUTPUT_DIR := go-idl/generated/gateway.go
# directories for Go code generation
IDL_DIR := target/idl
GENERATED_DIR := generated

# Generate go code
# generate Go code from IDL files
.PHONY: generate
generate:
go run $(GENERATOR_DIR) $(IDL_FILE) $(OUTPUT_DIR)
@for file in $(wildcard $(IDL_DIR)/*.json); do \
base_name=$$(basename $$file .json); \
output_file="$(GENERATED_DIR)/$$base_name.go"; \
echo "Generating $$output_file from $$file"; \
(cd go-idl && go run generator/main.go "$$file" "$$output_file"); \
done

# clean generated files
clean:
rm -rf $(GENERATED_DIR)/*.go
97 changes: 65 additions & 32 deletions go-idl/generator/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,25 @@ import (
"github.com/protocol-contracts-solana/go-idl/types"
)

const (
codeGenerationDisclaimer = `// Code generated by go-idl. DO NOT EDIT.`
idlPrefix = "IDL"
discrimatorNamePrefix = "Discriminator"
)

// generateIDLFile generates the Go code for the IDL struct.
func generateIDLFile(packagename, varname string, idl *types.IDL) string {
var sb strings.Builder

// header
sb.WriteString(fmt.Sprintf("%s\n", codeGenerationDisclaimer))
sb.WriteString(fmt.Sprintf("package %s\n\n", packagename))
sb.WriteString("import (\n")
sb.WriteString(" \"github.com/protocol-contracts-solana/go-idl/types\"\n")
sb.WriteString(")\n\n")

// IDL struct
sb.WriteString(fmt.Sprintf("var %s IDL = ", varname))
sb.WriteString(fmt.Sprintf("var %s%s = ", idlPrefix, varname))
sb.WriteString(generateIDLTypeCode(idl))

return sb.String()
Expand All @@ -28,61 +35,84 @@ func generateIDLFile(packagename, varname string, idl *types.IDL) string {
func generateIDLTypeCode(idl *types.IDL) string {
var sb strings.Builder

sb.WriteString(fmt.Sprintf("IDL{\n"))
sb.WriteString(fmt.Sprintf("types.IDL{\n"))
sb.WriteString(fmt.Sprintf(" Address: %q,\n", idl.Address))
sb.WriteString(fmt.Sprintf(" Metadata: Metadata{\n"))
sb.WriteString(fmt.Sprintf(" Metadata: types.Metadata{\n"))
sb.WriteString(fmt.Sprintf(" Name: %q,\n", idl.Metadata.Name))
sb.WriteString(fmt.Sprintf(" Version: %q,\n", idl.Metadata.Version))
sb.WriteString(fmt.Sprintf(" Spec: %q,\n", idl.Metadata.Spec))
sb.WriteString(fmt.Sprintf(" Description: %q,\n", idl.Metadata.Description))
sb.WriteString(" },\n")

// write instructions
sb.WriteString(" Instructions: []Instruction{\n")
sb.WriteString(" Instructions: []types.Instruction{\n")
for _, instr := range idl.Instructions {
sb.WriteString(" {\n")
sb.WriteString(fmt.Sprintf(" Name: %q,\n", instr.Name))
sb.WriteString(fmt.Sprintf(" Discriminator: %v,\n", instr.Discriminator))
sb.WriteString(" Accounts: []Account{\n")
sb.WriteString(fmt.Sprintf(" Discriminator: %v,\n", generateDiscriminatorCode(
instr.Discriminator,
)))
sb.WriteString(" Accounts: []types.Account{\n")
for _, acc := range instr.Accounts {
sb.WriteString(generateAccountCode(acc))
}
sb.WriteString(" },\n")
sb.WriteString(" Args: []Arg{\n")
for _, arg := range instr.Args {
sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", arg.Name, arg.Type))
}
sb.WriteString(" },\n")

// TODO: args generation
//sb.WriteString(" Args: []types.Arg{\n")
//for _, arg := range instr.Args {
// sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", arg.Name, arg.Type))
//}
//sb.WriteString(" },\n")

sb.WriteString(" },\n")
}
sb.WriteString(" },\n")

// write accounts
sb.WriteString(" Accounts: []Account{\n")
sb.WriteString(" Accounts: []types.Account{\n")
for _, acc := range idl.Accounts {
sb.WriteString(generateAccountCode(acc))
}
sb.WriteString(" },\n")

// write errors
sb.WriteString(" Errors: []Error{\n")
sb.WriteString(" Errors: []types.Error{\n")
for _, err := range idl.Errors {
sb.WriteString(fmt.Sprintf(" {Code: %d, Name: %q, Msg: %q},\n", err.Code, err.Name, err.Msg))
}
sb.WriteString(" },\n")

// write types
sb.WriteString(" Types: []Type{\n")
for _, typ := range idl.Types {
sb.WriteString(fmt.Sprintf(" {Name: %q, Type: TypeField{Kind: %q, Fields: []Field{\n", typ.Name, typ.Type.Kind))
for _, field := range typ.Type.Fields {
sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", field.Name, field.Type))
// TODO: types generation
//sb.WriteString(" Types: []types.Type{\n")
//for _, typ := range idl.Types {
// sb.WriteString(fmt.Sprintf(" {Name: %q, Type: TypeField{Kind: %q, Fields: []Field{\n", typ.Name, typ.Type.Kind))
// for _, field := range typ.Type.Fields {
// sb.WriteString(fmt.Sprintf(" {Name: %q, Type: %v},\n", field.Name, field.Type))
// }
// sb.WriteString(" }}},\n")
//}
//sb.WriteString(" },\n")

sb.WriteString("}\n")
return sb.String()
}

// generateDiscriminatorCode generates the Go code for a discriminator.
// use format [8]byte{...}
func generateDiscriminatorCode(discriminator [8]byte) string {
var sb strings.Builder

sb.WriteString("[8]byte{")
for i, b := range discriminator {
sb.WriteString(fmt.Sprintf("%d", b))
if i < len(discriminator)-1 {
sb.WriteString(", ")
}
sb.WriteString(" }}},\n")
}
sb.WriteString(" },\n")
sb.WriteString("}")

sb.WriteString("}\n")
return sb.String()
}

Expand All @@ -96,17 +126,20 @@ func generateAccountCode(acc types.Account) string {
sb.WriteString(fmt.Sprintf(" Signer: %t,\n", acc.Signer))
sb.WriteString(fmt.Sprintf(" Address: %q,\n", acc.Address))

if acc.PDA != nil {
sb.WriteString(" PDA: &PDA{\n")
sb.WriteString(" Seeds: []Seed{\n")
for _, seed := range acc.PDA.Seeds {
sb.WriteString(fmt.Sprintf(" {Kind: %q, Value: %v},\n", seed.Kind, seed.Value))
}
sb.WriteString(" },\n")
sb.WriteString(" },\n")
} else {
sb.WriteString(" PDA: nil,\n")
}
// TODO: PDA generation
//if acc.PDA != nil {
// sb.WriteString(" PDA: &types.PDA{\n")
// sb.WriteString(" Seeds: []types.Seed{\n")
// for _, seed := range acc.PDA.Seeds {
// sb.WriteString(fmt.Sprintf(" {Kind: %q, Value: %v},\n", seed.Kind, seed.Value))
// }
// sb.WriteString(" },\n")
// sb.WriteString(" },\n")
//} else {
// sb.WriteString(" PDA: nil,\n")
//}

sb.WriteString(" PDA: nil,\n")

sb.WriteString(" },\n")
return sb.String()
Expand Down
2 changes: 1 addition & 1 deletion go-idl/generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func writeGoFile(idl *types.IDL, outputPath string) error {
}

// write the Go code to the file
_, err = file.WriteString(generateIDLFile("solana", "IDL", idl))
_, err = file.WriteString(generateIDLFile("solana", "Gateway", idl))
if err != nil {
return fmt.Errorf("failed to write to file: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion go-idl/types/idl.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Metadata struct {

type Instruction struct {
Name string `json:"name"`
Discriminator []byte `json:"discriminator"`
Discriminator [8]byte `json:"discriminator"`
Accounts []Account `json:"accounts"`
Args []Arg `json:"args"`
}
Expand Down

0 comments on commit 8ebbb0b

Please sign in to comment.