code: func (sl *SchemaLoader) Compile(rootSchema JSONLoader) (*Schema, error) {
  
  	ref, err := rootSchema.JsonReference()
  
  	if err != nil {
  		return nil, err
  	}
  
  	d := Schema{}
  	d.pool = sl.pool
  	d.pool.jsonLoaderFactory = rootSchema.LoaderFactory()
  	d.documentReference = ref
  	d.referencePool = newSchemaReferencePool()
  
  	var doc interface{}
  	if ref.String() != "" {
  		// Get document from schema pool
  		spd, err := d.pool.GetDocument(d.documentReference)
  		if err != nil {
  			return nil, err
  		}
  		doc = spd.Document
  	} else {
  		// Load JSON directly
  		doc, err = rootSchema.LoadJSON()
  		if err != nil {
  			return nil, err
  		}
  		// References need only be parsed if loading JSON directly
  		//  as pool.GetDocument already does this for us if loading by reference
  		err = sl.pool.parseReferences(doc, ref, true)
  		if err != nil {
  			return nil, err
  		}
  	}
  
  	if sl.Validate {
  		if err := sl.validateMetaschema(doc); err != nil {
  			return nil, err
  		}
  	}
  
  	draft := sl.Draft
  	if sl.AutoDetect {
  		_, detectedDraft, err := parseSchemaURL(doc)
  		if err != nil {
  			return nil, err
  		}
  		if detectedDraft != nil {
  			draft = *detectedDraft
  		}
  	}
  
  	err = d.parse(doc, draft)
  	if err != nil {
  		return nil, err
  	}
  
  	return &d, nil
  }
docs: // Compile loads and compiles a schema