Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement of 'ref' mechanism #217

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions pkg/concepts/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,24 @@ type Type struct {
annotatedSupport
namedSupport

owner *Version
kind TypeKind
attributes AttributeSlice
values EnumValueSlice
element *Type
index *Type
owner *Version
kind TypeKind
attributes AttributeSlice
values EnumValueSlice
element *Type
index *Type
explicitDeclared bool
}

// ExplicitDeclared returns true if this type is explicitDeclared
// with a reference
func (t *Type) ExplicitDeclared() bool {
return t.explicitDeclared
}

// SetExplicitDeclared sets ExplicitDeclared
func (t *Type) SetExplicitDeclared(value bool) {
t.explicitDeclared = value
}

// Owner returns the version that owns this type.
Expand Down Expand Up @@ -193,6 +205,14 @@ func (t *Type) AddAttribute(attribute *Attribute) {
}
}

func (t *Type) AddAttributes(attributes AttributeSlice) {
if attributes.Len() > 0 {
for _, att := range attributes {
t.AddAttribute(att)
}
}
}

// FindAttribute returns the attribute with the given name, or nil if no such attribute exists.
func (t *Type) FindAttribute(name *names.Name) *Attribute {
for _, attribute := range t.attributes {
Expand Down
6 changes: 3 additions & 3 deletions pkg/generators/golang/json_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ func (g *JSONSupportGenerator) generateStructTypeSource(typ *concepts.Type) {
{{ $fieldTag := fieldTag . }}
{{ $fieldMask := bitMask . }}
case "{{ $fieldTag }}":
{{ generateReadValue "value" .Type .Link .LinkOwner}}
{{ generateReadValue "value" .Type .Link .LinkOwner }}
object.{{ $fieldName }} = value
object.bitmap_ |= {{ $fieldMask }}
{{ end }}
Expand Down Expand Up @@ -1351,7 +1351,7 @@ func (g *JSONSupportGenerator) generateReadValue(variable string, typ *concepts.
{{ .Variable }} := {{ readRefTypeFunc .Type .LinkOwner }}(iterator)
{{ else if .Type.IsList }}
{{ if .Link }}
{{ $selectorFromLinkOwner := selectorFromLinkOwner .LinkOwner}}
{{ $selectorFromLinkOwner := selectorFromLinkOwner .LinkOwner }}
{{ $structName := structName .Type }}
{{ .Variable }} := &{{ $selectorFromLinkOwner }}{{ $structName }}{}
for {
Expand Down Expand Up @@ -1485,7 +1485,7 @@ func (g *JSONSupportGenerator) generateWriteValue(value string,
}
item := {{ .Value }}[key]
stream.WriteObjectField(key)
{{ generateWriteValue "item" .Type.Element false .LinkOwner}}
{{ generateWriteValue "item" .Type.Element false .LinkOwner }}
}
stream.WriteObjectEnd()
} else {
Expand Down
51 changes: 47 additions & 4 deletions pkg/language/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,10 +431,34 @@ func (r *Reader) ExitClassDecl(ctx *ClassDeclContext) {
}

if path := annotations.ReferencePath(typ); path != "" {
// If the type has a reference set ExplicitDeclared
typ.SetExplicitDeclared(true)
r.removeLinkedAttributes(typ)
r.handleClassRef(typ, path)
}
}

func (r *Reader) removeLinkedAttributes(typ *concepts.Type) {
for _, types := range r.version.Types() {
for _, attribute := range types.Attributes() {
// It could be that the type is already in an attribute of the service
// It needs to add the SetExplicitDeclared to it. {
if attribute.Type().Name() == typ.Name() {
attribute.SetLinkOwner(nil)
attribute.Type().SetExplicitDeclared(true)
}
if attribute.Type().IsList() || attribute.Type().IsMap() {
if attribute.Type().Element().Name().String() == typ.Name().String() {
attribute.SetLinkOwner(nil)
attribute.Type().SetExplicitDeclared(true)
attribute.Type().Element().SetExplicitDeclared(true)
attribute.Type().Element().SetOwner(typ.Owner())
}
}
}
}
}

func (r *Reader) handleClassRef(typ *concepts.Type, path string) {
if len(r.inputs) > 1 {
panic("referenced service with multiple inputs in undefined")
Expand Down Expand Up @@ -462,7 +486,6 @@ func (r *Reader) handleClassRef(typ *concepts.Type, path string) {
// Once loading the service, we find the reference type
// then recursively iterate the type tree and add the types to the current version.
if referencedType := refVersion.FindType(names.ParseUsingSeparator(referencedTypeName, "_")); referencedType != nil {
r.version.AddType(referencedType)
r.recursivelyAddTypeToVersion(typ, referencedType)
}
}
Expand All @@ -474,9 +497,25 @@ func (r *Reader) recursivelyAddTypeToVersion(currType *concepts.Type,
return
}
for _, attribute := range referencedType.Attributes() {
// If attribute is explicitDeclared, it needs to change it's owner to be the same as currType
if attribute.Link() {
// If the attribute is a Link set the LinkOwner
// to the attribute type Owner
// to the attribute type Owner, if it is also a list it should change the owner of the
// element type
existingAttType := r.version.FindType(attribute.Type().Name())
if existingAttType != nil && existingAttType.ExplicitDeclared() {
attribute.Type().SetOwner(r.version)
// Stop the iteration over the attributes of this type
continue
} else if attribute.Type().IsList() || attribute.Type().IsMap() {
existingAttType = r.version.FindType(attribute.Type().Element().Name())
if existingAttType != nil && existingAttType.ExplicitDeclared() {
attribute.Type().SetOwner(r.version)
attribute.Type().Element().SetOwner(r.version)
continue
}
}
// Otherwise add the setLinkOwner to the attribute
attribute.SetLinkOwner(attribute.Type().Owner())
} else if attribute.Type().IsList() || attribute.Type().IsMap() {
r.version.AddType(attribute.Type())
Expand All @@ -485,9 +524,13 @@ func (r *Reader) recursivelyAddTypeToVersion(currType *concepts.Type,
r.recursivelyAddTypeToVersion(currType, attribute.Type())
}
}
if r.version.FindType(referencedType.Name()) == nil {
r.version.AddType(referencedType)

existingType := r.version.FindType(referencedType.Name())
if existingType != nil && existingType.ExplicitDeclared() {
referencedType.SetExplicitDeclared(true)
}
r.version.AddType(referencedType)

}

func (r *Reader) ExitStructDecl(ctx *StructDeclContext) {
Expand Down
9 changes: 3 additions & 6 deletions pkg/language/ref_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ var _ = Describe("Read Model with ref annotation", func() {
attributeFoo := class.FindAttribute(names.ParseUsingCase("Foo"))
Expect(attributeFoo).ToNot(BeNil())
Expect(attributeFoo.Type().IsList()).To(BeTrue())
Expect(attributeFoo.LinkOwner().Name().String()).To(Equal("v1"))
Expect(attributeFoo.Type().Owner().Name().String()).To(Equal("v1"))
Expect(attributeFoo.Type().Owner().Name().String()).To(Equal("v1_alpha1"))
myAttributeType := version.FindType(names.ParseUsingCase("MyAttribute"))
Expect(myAttributeType).ToNot(BeNil())
Expect(myAttributeType.Owner().Name().String()).To(Equal("v1_alpha1"))
Expand Down Expand Up @@ -267,8 +266,7 @@ var _ = Describe("Read Model with ref annotation", func() {
attributeFoo := class.FindAttribute(names.ParseUsingCase("Foo"))
Expect(attributeFoo).ToNot(BeNil())
Expect(attributeFoo.Type().IsList()).To(BeTrue())
Expect(attributeFoo.LinkOwner().Name().String()).To(Equal("v1"))
Expect(attributeFoo.Type().Owner().Name().String()).To(Equal("v1"))
Expect(attributeFoo.Type().Owner().Name().String()).To(Equal("v1_alpha1"))
myAttributeType := version.FindType(names.ParseUsingCase("MyAttribute"))
Expect(myAttributeType).ToNot(BeNil())
Expect(myAttributeType.Owner().Name().String()).To(Equal("v1_alpha1"))
Expand Down Expand Up @@ -331,8 +329,7 @@ var _ = Describe("Read Model with ref annotation", func() {
attributeFoo := class.FindAttribute(names.ParseUsingCase("Foo"))
Expect(attributeFoo).ToNot(BeNil())
Expect(attributeFoo.Type().IsList()).To(BeTrue())
Expect(attributeFoo.LinkOwner().Name().String()).To(Equal("v1"))
Expect(attributeFoo.Type().Owner().Name().String()).To(Equal("v1"))
Expect(attributeFoo.Type().Owner().Name().String()).To(Equal("v1_alpha1"))
myAttributeType := version.FindType(names.ParseUsingCase("MyAttribute"))
Expect(myAttributeType).ToNot(BeNil())
Expect(myAttributeType.Owner().Name().String()).To(Equal("v1_alpha1"))
Expand Down
7 changes: 6 additions & 1 deletion tests/model/aro_hcp/v1_alpha1/cluster_resource.model
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ resource Cluster {
locator NodePools {
target NodePools
}
}

// Reference to the resource that manages the detailed status of the cluster.
locator Status {
target ClusterStatus
}
}
23 changes: 23 additions & 0 deletions tests/model/aro_hcp/v1_alpha1/cluster_status_resource.model
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright (c) 2025 Red Hat, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Manages a specific cluster status.
resource ClusterStatus {
// Retrieves the details of the node pool.
method Get {
out Body ClusterStatus
}
}
19 changes: 19 additions & 0 deletions tests/model/aro_hcp/v1_alpha1/cluster_status_type.model
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright (c) 2025 Red Hat, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

@ref(path = "/clusters_mgmt/v1/cluster_status")
class ClusterStatus {
}
2 changes: 1 addition & 1 deletion tests/model/aro_hcp/v1_alpha1/cluster_type.model
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ limitations under the License.

@ref(path = "/clusters_mgmt/v1/cluster")
class Cluster {
}
}
2 changes: 1 addition & 1 deletion tests/model/aro_hcp/v1_alpha1/clusters_resource.model
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ resource Clusters {
target Cluster
variable ID
}
}
}
2 changes: 1 addition & 1 deletion tests/model/aro_hcp/v1_alpha1/node_pool_type.model
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ limitations under the License.

@ref(path = "/clusters_mgmt/v1/node_pool")
class NodePool {
}
}
2 changes: 1 addition & 1 deletion tests/model/aro_hcp/v1_alpha1/node_pools_resource.model
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ resource NodePools {
target NodePool
variable ID
}
}
}
10 changes: 10 additions & 0 deletions tests/model/clusters_mgmt/v1/cluster_resource.model
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,14 @@ resource Cluster {
locator IdentityProviders {
target IdentityProviders
}

// Reference to the NodePool resource
locator NodePools{
target NodePools
}

// Reference to the resource that manages the detailed status of the cluster.
locator Status {
target ClusterStatus
}
}
23 changes: 23 additions & 0 deletions tests/model/clusters_mgmt/v1/cluster_status_resource.model
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright (c) 2025 Red Hat, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Manages a specific cluster status.
resource ClusterStatus {
// Retrieves the details of the node pool.
method Get {
out Body ClusterStatus
}
}
24 changes: 24 additions & 0 deletions tests/model/clusters_mgmt/v1/cluster_status_type.model
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Copyright (c) 2025 Red Hat, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Overall state of a cluster.
class ClusterStatus {
// State value
State ClusterState

// Human readable value
Message String
}
10 changes: 9 additions & 1 deletion tests/model/clusters_mgmt/v1/cluster_type.model
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ class Cluster {
// User defined properties for tagging and querying.
Properties [String]String

// Overall state of the cluster.
// Overall status of the cluster.
Status ClusterStatus

// Overall state of the cluster
State ClusterState

// Flag indicating if the cluster is managed (by Red Hat) or
Expand Down Expand Up @@ -67,4 +70,9 @@ class Cluster {

// Floating point value used for tests.
Factor Float

// List of node pools on this cluster.
// NodePool is a scalable set of worker nodes attached to a hosted cluster.
link NodePools []NodePool

}
32 changes: 32 additions & 0 deletions tests/model/clusters_mgmt/v1/node_pool_resource.model
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Copyright (c) 2025 Red Hat, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Manages a specific nodepool.
resource NodePool {
// Retrieves the details of the node pool.
method Get {
out Body NodePool
}

// Updates the node pool.
method Update {
in out Body NodePool
}

// Deletes the node pool.
method Delete {
}
}
Loading