Skip to content

Go Library Reference

Installation

go get github.com/grokify/pidl

Packages

Package Description
github.com/grokify/pidl Core types, parsing, execution, comparison, debugging
github.com/grokify/pidl/render Diagram and trace rendering
github.com/grokify/pidl/examples Built-in examples
github.com/grokify/pidl/schema Embedded JSON Schema
github.com/grokify/pidl/analyze Security analysis and rules

Core Types

Protocol

type Protocol struct {
    ProtocolMeta ProtocolMeta `json:"protocol"`
    Entities     []Entity     `json:"entities"`
    Phases       []Phase      `json:"phases,omitempty"`
    Flows        []Flow       `json:"flows"`
}

Entity

type Entity struct {
    ID          string     `json:"id"`
    Name        string     `json:"name"`
    Type        EntityType `json:"type"`
    Description string     `json:"description,omitempty"`
}

Phase

type Phase struct {
    ID          string `json:"id"`
    Name        string `json:"name"`
    Description string `json:"description,omitempty"`
    Parent      string `json:"parent,omitempty"`
}

Flow

type Flow struct {
    From         string        `json:"from"`
    To           string        `json:"to"`
    Action       string        `json:"action"`
    Label        string        `json:"label,omitempty"`
    Mode         FlowMode      `json:"mode,omitempty"`
    Phase        string        `json:"phase,omitempty"`
    Description  string        `json:"description,omitempty"`
    Sequence     int           `json:"sequence,omitempty"`
    Condition    string        `json:"condition,omitempty"`
    Note         string        `json:"note,omitempty"`
    Annotations  []Annotation  `json:"annotations,omitempty"`
    Alternatives []Alternative `json:"alternatives,omitempty"`
}

Annotation

type Annotation struct {
    Type    AnnotationType `json:"type"`
    Text    string         `json:"text"`
    Details string         `json:"details,omitempty"`
}

Alternative

type Alternative struct {
    Condition   string `json:"condition"`
    Flows       []Flow `json:"flows"`
    Description string `json:"description,omitempty"`
}

Parsing

// Parse from file
p, err := pidl.ParseFile("protocol.json")

// Parse from bytes
p, err := pidl.Parse(jsonBytes)

// Parse from reader
p, err := pidl.ParseReader(reader)

// Must parse (panics on error)
p := pidl.MustParse(jsonBytes)

Validation

// Validate and get errors
errs := p.Validate()
if errs.HasErrors() {
    for _, e := range errs {
        fmt.Printf("%s: %s\n", e.Field, e.Message)
    }
}

// Quick validity check
if p.IsValid() {
    // proceed
}

Protocol Methods

// Find entities/phases
entity := p.EntityByID("client")
phase := p.PhaseByID("auth")

// Get flows by phase
flows := p.FlowsByPhase("auth")

// Get all IDs
entityIDs := p.EntityIDs()
phaseIDs := p.PhaseIDs()

// Phase hierarchy
roots := p.RootPhases()
children := p.ChildPhases("auth")
depth := p.PhaseDepth("mfa")

Flow Methods

// Display helpers
label := flow.DisplayLabel()  // Label or Action
mode := flow.EffectiveMode()  // Mode or FlowModeRequest

// Feature checks
if flow.HasCondition() { ... }
if flow.HasNote() { ... }
if flow.HasAnnotations() { ... }
if flow.HasAlternatives() { ... }

Rendering

import "github.com/grokify/pidl/render"

// Create renderer
r := render.NewMermaid()
r := render.NewPlantUML()
r := render.NewD2()
r := render.NewDOT()

// Render to string
diagram, err := r.RenderString(p)

// Render to writer
err := r.Render(os.Stdout, p)

// Quick render by format
diagram, err := render.RenderString(render.FormatMermaid, p)

Examples Package

import "github.com/grokify/pidl/examples"

// List available examples
names := examples.List()

// Get example JSON
jsonBytes, err := examples.GetJSON("oauth2_authorization_code")

// Get parsed protocol
p, err := examples.GetProtocol("oauth2_authorization_code")

// Get all protocols
all, err := examples.All()

Creating Protocols

// Create minimal protocol
p := pidl.NewMinimalProtocol("my-protocol", "My Protocol")

// Write to file
err := pidl.WriteProtocolFile("output.json", p)

Full Example

package main

import (
    "fmt"
    "log"

    "github.com/grokify/pidl"
    "github.com/grokify/pidl/render"
    "github.com/grokify/pidl/examples"
)

func main() {
    // Load built-in example
    p, err := examples.GetProtocol("oauth2_pkce")
    if err != nil {
        log.Fatal(err)
    }

    // Validate
    if errs := p.Validate(); errs.HasErrors() {
        log.Fatal(errs)
    }

    // Generate Mermaid diagram
    r := render.NewMermaid()
    r.Autonumber = true

    diagram, err := r.RenderString(p)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(diagram)
}

Protocol Comparison

// Compare two protocols
diff := pidl.Compare(baseProtocol, newProtocol, pidl.DiffOptions{
    IgnoreMetadata: false,
})

// Check for differences
if diff.HasChanges() {
    fmt.Println(diff.String())
}

// Output as JSON or Markdown
jsonBytes, _ := diff.ToJSON()
markdown := diff.ToMarkdown()

// Access summary
fmt.Printf("Added: %d, Removed: %d, Modified: %d\n",
    diff.Summary.Added, diff.Summary.Removed, diff.Summary.Modified)

Protocol Simulation

// Create executor
executor := pidl.NewExecutor(protocol)

// Optional: custom condition evaluator
executor.ConditionEvaluator = func(ctx *pidl.ExecutionContext, flow *pidl.Flow) bool {
    return true // evaluate condition
}

// Execute full protocol
trace, err := executor.Execute()

// Step-by-step execution
ctx := executor.NewContext()
for !ctx.Completed {
    step, err := executor.Step(ctx)
    if err != nil {
        break
    }
    fmt.Printf("Step %d: %s -> %s\n", step.StepNumber, step.From, step.To)
}

// Access trace
fmt.Println(trace.String())
jsonBytes, _ := trace.ToJSON()

Interactive Debugger

// Create debug session
session := pidl.NewDebugSession(protocol)

// Set breakpoints
session.SetBreakpoint(3, "")                    // Unconditional
session.SetBreakpoint(5, "client.state == \"waiting\"") // Conditional

// Step through execution
step, _ := session.Step()
fmt.Printf("Executed: %s\n", step.Action)

// Continue until breakpoint
session.Continue()

// Inspect state
state := session.Inspect()
fmt.Printf("Flow %d, Completed: %v\n", state.FlowIndex, state.IsCompleted)
fmt.Printf("Entity states: %v\n", state.EntityStates)

// Inspect specific entity
entity, entityState, _ := session.InspectEntity("client")
fmt.Printf("%s is in state: %s\n", entity.Name, entityState)

// Modify state
session.SetEntityState("client", "authenticated")

// Reset and restart
session.Reset()

// List flows with markers
fmt.Println(session.FormatFlowList())

Security Analysis

import "github.com/grokify/pidl/analyze"

// Run analysis with default options
analysis := analyze.Analyze(protocol, analyze.DefaultAnalysisOptions())

// Custom options
opts := analyze.AnalysisOptions{
    MinSeverity:   analyze.SeverityMedium,
    Categories:    []analyze.RiskCategory{analyze.CategoryAuthentication},
    DisabledRules: []string{"SEC008"},
}
analysis = analyze.Analyze(protocol, opts)

// Check results
if analysis.HasRisks() {
    fmt.Println(analysis.String())
}

if analysis.HasRisksAtOrAbove(analyze.SeverityHigh) {
    // Critical action needed
}

// Filter risks
authRisks := analysis.RisksByCategory(analyze.CategoryAuthentication)
highRisks := analysis.RisksBySeverity(analyze.SeverityHigh)

// Output formats
fmt.Println(analysis.ToMarkdown())
jsonBytes, _ := analysis.ToJSON()

// Access summary
fmt.Printf("Score: %d/100, Total: %d risks\n",
    analysis.Summary.Score, analysis.Summary.TotalRisks)

Trace Rendering

import "github.com/grokify/pidl/render"

// Create trace renderer
tr := render.NewTraceRenderer()
tr.ShowStates = true
tr.ShowTimings = true

// Render as text
text := tr.RenderText(trace, render.TraceTextOptions{
    ShowTimestamps: true,
    ShowStates:     true,
    UseColors:      true,
})

// Render as SVG
svg, _ := tr.RenderSVG(trace, protocol)

// Render as Mermaid
mermaid := tr.RenderMermaid(trace, protocol)
```