Skip to content

Commit

Permalink
objects can have properties (#30)
Browse files Browse the repository at this point in the history
Closes #26

This allows us to write objects inline with properties.
  • Loading branch information
rambleraptor authored Oct 11, 2024
1 parent 71f7d30 commit e25a0bf
Show file tree
Hide file tree
Showing 13 changed files with 547 additions and 334 deletions.
350 changes: 219 additions & 131 deletions example/bookstore/v1/bookstore.pb.go

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions example/bookstore/v1/bookstore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ service Bookstore {

// A Book resource.
message Book {
message Author {
// Field for firstName.
string firstName = 1;

// Field for lastName.
string lastName = 2;
}

// Field for author.
repeated Author author = 5;

// Field for isbn.
repeated string isbn = 1 [(google.api.field_behavior) = REQUIRED];

Expand Down
21 changes: 21 additions & 0 deletions example/bookstore/v1/bookstore.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@
}
},
"definitions": {
"BookAuthor": {
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "Field for firstName."
},
"lastName": {
"type": "string",
"description": "Field for lastName."
}
}
},
"protobufAny": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -298,6 +311,14 @@
"v1Book": {
"type": "object",
"properties": {
"author": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/BookAuthor"
},
"description": "Field for author."
},
"isbn": {
"type": "array",
"items": {
Expand Down
10 changes: 10 additions & 0 deletions example/bookstore/v1/bookstore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ resources:
type: INT32
number: 4
required: false
author:
array_type:
object_type:
properties:
firstName:
type: STRING
number: 1
lastName:
type: STRING
number: 2
# parents:
# - "bookstore.example.com/Publisher"
methods:
Expand Down
6 changes: 6 additions & 0 deletions example/bookstore/v1/bookstore_openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@
"published"
],
"properties": {
"author": {
"type": "array",
"items": {
"type": "object"
}
},
"edition": {
"type": "integer",
"format": "int32"
Expand Down
32 changes: 18 additions & 14 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ func NewParsedService(s *schema.Service) (*ParsedService, error) {
func ParsedResourceForObject(r *schema.Object, s *schema.Service) *ParsedResource {
t := fmt.Sprintf("%s/%s", s.Name, r.Kind)
return &ParsedResource{
Type: t,
Resource: &schema.Resource{
Kind: r.Kind,
Properties: r.Properties,
},
IsResource: false,
}
Type: t,
Resource: &schema.Resource{
Kind: r.Kind,
Properties: r.Properties,
},
IsResource: false,
}
}

func loadObjectsByType(o []*schema.Object, s *schema.Service, m *map[string]*ParsedResource) (error) {
func loadObjectsByType(o []*schema.Object, s *schema.Service, m *map[string]*ParsedResource) error {
for _, r := range o {
t := fmt.Sprintf("%s/%s", s.Name, r.Kind)
(*m)[t] = ParsedResourceForObject(r, s)
Expand All @@ -79,9 +79,9 @@ func loadResourceByType(s *schema.Service) (map[string]*ParsedResource, error) {
for _, r := range s.Resources {
t := fmt.Sprintf("%s/%s", s.Name, r.Kind)
resourceByType[t] = &ParsedResource{
Resource: r,
Type: t,
Parents: []*ParsedResource{},
Resource: r,
Type: t,
Parents: []*ParsedResource{},
IsResource: true,
}
}
Expand All @@ -106,10 +106,14 @@ func loadResourceByType(s *schema.Service) (map[string]*ParsedResource, error) {
}

func (pr *ParsedResource) GetPropertiesSortedByNumber() []*ParsedProperty {
return PropertiesSortedByNumber(pr.Properties)
}

func PropertiesSortedByNumber(properties map[string]*schema.Property) []*ParsedProperty {
// to ensure idempotency of generators, fields are ordered by
// field number
parsedProperties := []*ParsedProperty{}
for name, p := range pr.Properties {
for name, p := range properties {
parsedProperties = append(parsedProperties, &ParsedProperty{
Property: p,
Name: name,
Expand All @@ -134,12 +138,12 @@ func addGetToResource(pr *ParsedResource) {
// existence of path.
func addCommonFieldsToResource(pr *ParsedResource) {
pr.Properties[constants.FIELD_PATH_NAME] = &schema.Property{
Types: &schema.Property_Type{Type: schema.Type_STRING},
Types: &schema.Property_Type{Type: schema.Type_STRING},
Number: 10000,
ReadOnly: true,
}
pr.Properties[constants.FIELD_ID_NAME] = &schema.Property{
Types: &schema.Property_Type{Type: schema.Type_STRING},
Types: &schema.Property_Type{Type: schema.Type_STRING},
Number: 10001,
ReadOnly: true,
}
Expand Down
104 changes: 50 additions & 54 deletions schema/resourcedefinition.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions schema/resourcedefinition.proto
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ message Property {
}

message ObjectType {
oneof object_details {
string message_name = 1;
}
// message_name and properties cannot both be set at the same time.
string message_name = 1;
map<string, Property> properties = 2;
}

message ArrayType {
Expand Down
18 changes: 18 additions & 0 deletions validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,23 @@ func validateResource(r *schema.Resource) []error {
fmt.Errorf("kind must match regex %q", RESOURCE_KIND_REGEX_STRING),
)
}

for _, p := range r.Properties {
errors = append(errors, validateProperty(p)...)
}
return errors
}

func validateProperty(p *schema.Property) []error {
errors := []error{}
switch p.GetTypes().(type) {
case *schema.Property_ObjectType:
if p.GetObjectType().GetMessageName() != "" && len(p.GetObjectType().GetProperties()) != 0 {
errors = append(errors, fmt.Errorf("cannot set both message_name and properties on object_type %q", p))
}
for _, p := range p.GetObjectType().GetProperties() {
errors = append(errors, validateProperty(p)...)
}
}
return errors
}
Loading

0 comments on commit e25a0bf

Please sign in to comment.