blob: e0859f795cbecd46d505cc57d12f70152124e593 [file] [log] [blame]
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.
package main
import (
"fmt"
"strings"
"github.com/googleapis/gnostic/jsonschema"
)
/// Type Modeling
// TypeRequest models types that we encounter during model-building that have no named schema.
type TypeRequest struct {
Name string // name of type to be created
PropertyName string // name of a property that refers to this type
Schema *jsonschema.Schema // schema for type
OneOfWrapper bool // true if the type wraps "oneOfs"
}
// NewTypeRequest creates a TypeRequest.
func NewTypeRequest(name string, propertyName string, schema *jsonschema.Schema) *TypeRequest {
return &TypeRequest{Name: name, PropertyName: propertyName, Schema: schema}
}
// TypeProperty models type properties, eg. fields.
type TypeProperty struct {
Name string // name of property
Type string // type for property (scalar or message type)
StringEnumValues []string // possible values if this is an enumerated string type
MapType string // if this property is for a map, the name of the mapped type
Repeated bool // true if this property is repeated (an array)
Pattern string // if the property is a pattern property, names must match this pattern.
Implicit bool // true if this property is implied by a pattern or "additional properties" property
Description string // if present, the "description" field in the schema
}
func (typeProperty *TypeProperty) description() string {
result := ""
if typeProperty.Description != "" {
result += fmt.Sprintf("\t// %+s\n", typeProperty.Description)
}
if typeProperty.Repeated {
result += fmt.Sprintf("\t%s %s repeated %s\n", typeProperty.Name, typeProperty.Type, typeProperty.Pattern)
} else {
result += fmt.Sprintf("\t%s %s %s \n", typeProperty.Name, typeProperty.Type, typeProperty.Pattern)
}
return result
}
// NewTypeProperty creates a TypeProperty
func NewTypeProperty() *TypeProperty {
return &TypeProperty{}
}
// NewTypePropertyWithNameAndType creates a TypeProperty
func NewTypePropertyWithNameAndType(name string, typeName string) *TypeProperty {
return &TypeProperty{Name: name, Type: typeName}
}
// NewTypePropertyWithNameTypeAndPattern creates a TypeProperty
func NewTypePropertyWithNameTypeAndPattern(name string, typeName string, pattern string) *TypeProperty {
return &TypeProperty{Name: name, Type: typeName, Pattern: pattern}
}
// FieldName returns the message field name to use for a property.
func (typeProperty *TypeProperty) FieldName() string {
propertyName := typeProperty.Name
if propertyName == "$ref" {
return "XRef"
}
return strings.Title(snakeCaseToCamelCase(propertyName))
}
// TypeModel models types.
type TypeModel struct {
Name string // type name
Properties []*TypeProperty // slice of properties
Required []string // required property names
OneOfWrapper bool // true if this type wraps "oneof" properties
Open bool // open types can have keys outside the specified set
OpenPatterns []string // patterns for properties that we allow
IsStringArray bool // ugly override
IsItemArray bool // ugly override
IsBlob bool // ugly override
IsPair bool // type is a name-value pair used to support ordered maps
PairValueType string // type for pair values (valid if IsPair == true)
Description string // if present, the "description" field in the schema
}
func (typeModel *TypeModel) addProperty(property *TypeProperty) {
if typeModel.Properties == nil {
typeModel.Properties = make([]*TypeProperty, 0)
}
typeModel.Properties = append(typeModel.Properties, property)
}
func (typeModel *TypeModel) description() string {
result := ""
if typeModel.Description != "" {
result += fmt.Sprintf("// %+s\n", typeModel.Description)
}
var wrapperinfo string
if typeModel.OneOfWrapper {
wrapperinfo = " oneof wrapper"
}
result += fmt.Sprintf("%+s%s\n", typeModel.Name, wrapperinfo)
for _, property := range typeModel.Properties {
result += property.description()
}
return result
}
// NewTypeModel creates a TypeModel.
func NewTypeModel() *TypeModel {
typeModel := &TypeModel{}
typeModel.Properties = make([]*TypeProperty, 0)
return typeModel
}