func (s *EntrySchema) IsSingleton() *EntrySchema {
	s.entrySchema.Singleton = true
	return s
}
IsSingleton marks the entry as a singleton entry.
package plugin
import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"
	"github.com/ekinanp/jsonschema"
	"github.com/emirpasic/gods/maps/linkedhashmap"
)
const registrySchemaLabel = "mountpoint"
func TypeID(e Entry) string {
	pluginName := pluginName(e)
	rawTypeID := rawTypeID(e)
	if pluginName == "" {
		return rawTypeID
	}
	return namespace(pluginName, rawTypeID)
}
func SchemaGraph(e Entry) (*linkedhashmap.Map, error) {
	s, err := schema(e)
	if err != nil {
		return nil, err
	}
	if s == nil {
		return nil, nil
	}
	if s.graph == nil {
		s.graph = linkedhashmap.New()
		s.fill(s.graph)
	}
	return s.graph, nil
}
func schema(e Entry) (*EntrySchema, error) {
	switch t := e.(type) {
	case externalPlugin:
		graph, err := t.SchemaGraph()
		if err != nil {
			return nil, err
		}
		if graph == nil {
			return nil, nil
		}
		s := NewEntrySchema(e, "foo")
		s.graph = graph
		entrySchemaV, _ := s.graph.Get(TypeID(e))
		s.entrySchema = entrySchemaV.(EntrySchema).entrySchema
		return s, nil
	case *Registry:
		schema := NewEntrySchema(t, registrySchemaLabel).
			IsSingleton().
			SetDescription(registryDescription)
		schema.graph = linkedhashmap.New()
		typeID := TypeID(t)
		schema.graph.Put(typeID, EntrySchema{})
		for _, root := range t.pluginRoots {
			childSchema, err := Schema(root)
			if err != nil {
				return nil, fmt.Errorf("failed to retrieve the %v plugin's schema: %v", root.eb().name, err)
			}
			if childSchema == nil {
				childSchema = NewEntrySchema(root, CName(root))
			}
			childSchema.IsSingleton()
			schema.Children = append(schema.Children, TypeID(childSchema.entry))
			childGraph := childSchema.graph
			if childGraph == nil {
				childGraph = linkedhashmap.New()
				childSchema.fill(childGraph)
			}
			childGraph.Each(func(key interface{}, value interface{}) {
				schema.graph.Put(key, value)
			})
		}
		schema.graph.Put(typeID, schema.clone())
		return schema, nil
	default:
		return e.Schema(), nil
	}
}
type entrySchema struct {
	Label                 string         `json:"label"`
	Description           string         `json:"description,omitempty"`
	Singleton             bool           `json:"singleton"`
	Signals               []SignalSchema `json:"signals,omitempty"`
	Actions               []string       `json:"actions"`
	PartialMetadataSchema *JSONSchema    `json:"partial_metadata_schema"`
	MetadataSchema        *JSONSchema    `json:"metadata_schema"`
	Children              []string       `json:"children"`
}
type EntrySchema struct {
	entrySchema
	partialMetadataSchemaObj interface{}
	metadataSchemaObj        interface{}
	entry Entry
	graph *linkedhashmap.Map
}
func NewEntrySchema(e Entry, label string) *EntrySchema {
	if len(label) == 0 {
		panic("plugin.NewEntrySchema called with an empty label")
	}
	s := &EntrySchema{
		entrySchema: entrySchema{
			Label:   label,
			Actions: SupportedActionsOf(e),
		},
		partialMetadataSchemaObj: struct{}{},
		entry:                    e,
	}
	return s
}
func (s EntrySchema) MarshalJSON() ([]byte, error) {
	if s.entry == nil {
		return json.Marshal(s.entrySchema)
	}
	graph := s.graph
	if graph == nil {
		if _, ok := s.entry.(externalPlugin); ok {
			msg := fmt.Sprintf(
				"s.MarshalJSON: called with a nil graph for external plugin entry %v (type ID %v)",
				CName(s.entry),
				TypeID(s.entry),
			)
			panic(msg)
		}
		graph = linkedhashmap.New()
		s.fill(graph)
	}
	return graph.ToJSON()
}
func (s *EntrySchema) SetDescription(description string) *EntrySchema {
	s.entrySchema.Description = strings.Trim(description, "\n")
	return s
}