openapi: Change reference to be first-class

References in the openapi are currently completely hidden from the
model, and just passed through as we walk the tree. The problem is that
they can have a different description and more importantly, different
extensions.

Change them to be first-class citizen, and fully part of the model. It
means that visitors have to implement one more function and decide if
something specific should be done with references. Validation is updated
to just completely ignore them and passthrough (like it was done
before).
This commit is contained in:
Antoine Pelisse
2017-08-23 14:11:16 -07:00
parent 2f00e6d72c
commit 5ef3516780
4 changed files with 57 additions and 42 deletions

View File

@@ -164,8 +164,9 @@ func (d *Definitions) parseReference(s *openapi_v2.Schema, path *Path) (Schema,
if _, ok := d.models[reference]; !ok {
return nil, newSchemaError(path, "unknown model in reference: %q", reference)
}
return &Reference{
Reference: reference,
return &Ref{
BaseSchema: d.parseBaseSchema(s, path),
reference: reference,
definitions: d,
}, nil
}
@@ -303,38 +304,27 @@ func (d *Definitions) LookupResource(gvk schema.GroupVersionKind) Schema {
return model
}
// SchemaReference doesn't match a specific type. It's mostly a
// pass-through type.
type Reference struct {
Reference string
type Ref struct {
BaseSchema
reference string
definitions *Definitions
}
var _ Schema = &Reference{}
var _ Reference = &Ref{}
func (r *Reference) GetSubSchema() Schema {
return r.definitions.models[r.Reference]
func (r *Ref) Reference() string {
return r.reference
}
func (r *Reference) Accept(s SchemaVisitor) {
r.GetSubSchema().Accept(s)
func (r *Ref) SubSchema() Schema {
return r.definitions.models[r.reference]
}
func (r *Reference) GetDescription() string {
return r.GetSubSchema().GetDescription()
func (r *Ref) Accept(v SchemaVisitor) {
v.VisitReference(r)
}
func (r *Reference) GetExtensions() map[string]interface{} {
return r.GetSubSchema().GetExtensions()
}
func (*Reference) GetPath() *Path {
// Reference never has a path, because it can be referenced from
// multiple locations.
return &Path{}
}
func (r *Reference) GetName() string {
return r.Reference
func (r *Ref) GetName() string {
return fmt.Sprintf("Reference to %q", r.reference)
}