| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 | // Copyright 2020 Google LLC. 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, softwis// 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 wellknownimport (	v3 "github.com/google/gnostic/openapiv3"	"google.golang.org/protobuf/reflect/protoreflect")func NewStringSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string"}}}}func NewBooleanSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "boolean"}}}}func NewBytesSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string", Format: "bytes"}}}}func NewIntegerSchema(format string) *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "integer", Format: format}}}}func NewNumberSchema(format string) *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "number", Format: format}}}}func NewEnumSchema(enum_type *string, field protoreflect.FieldDescriptor) *v3.SchemaOrReference {	schema := &v3.Schema{Format: "enum"}	if enum_type != nil && *enum_type == "string" {		schema.Type = "string"		schema.Enum = make([]*v3.Any, 0, field.Enum().Values().Len())		for i := 0; i < field.Enum().Values().Len(); i++ {			schema.Enum = append(schema.Enum, &v3.Any{				Yaml: string(field.Enum().Values().Get(i).Name()),			})		}	} else {		schema.Type = "integer"	}	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: schema}}}func NewListSchema(item_schema *v3.SchemaOrReference) *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{				Type:  "array",				Items: &v3.ItemsItem{SchemaOrReference: []*v3.SchemaOrReference{item_schema}},			},		},	}}// google.api.HttpBody will contain POST body data// This is based on how Envoy handles google.api.HttpBodyfunc NewGoogleApiHttpBodySchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string"}}}}// google.protobuf.Timestamp is serialized as a stringfunc NewGoogleProtobufTimestampSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string", Format: "date-time"}}}}// google.protobuf.Duration is serialized as a stringfunc NewGoogleProtobufDurationSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			// From: https://github.com/protocolbuffers/protobuf/blob/ece5ef6b9b6fa66ef4638335612284379ee4548f/src/google/protobuf/duration.proto			// In JSON format, the Duration type is encoded as a string rather than an			// object, where the string ends in the suffix "s" (indicating seconds) and			// is preceded by the number of seconds, with nanoseconds expressed as			// fractional seconds. For example, 3 seconds with 0 nanoseconds should be			// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should			// be expressed in JSON format as "3.000000001s", and 3 seconds and 1			// microsecond should be expressed in JSON format as "3.000001s".			//			// The fields of message google.protobuf.Duration are further described as:			// "int64 seconds"			// Signed seconds of the span of time. Must be from -315,576,000,000			// to +315,576,000,000 inclusive. Note: these bounds are computed from:			// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years			// `int32 nanos`			// Signed fractions of a second at nanosecond resolution of the span			// of time. Durations less than one second are represented with a 0			// `seconds` field and a positive or negative `nanos` field. For durations			// of one second or more, a non-zero value for the `nanos` field must be			// of the same sign as the `seconds` field. Must be from -999,999,999			// to +999,999,999 inclusive.			//			// This leads to the regex below limiting range from -315.576,000,000s to 315,576,000,000s			// allowing -0.999,999,999s to 0.999,999,999s in the floating precision range.			// That full range cannot be expressed precisly in float64 as demonstrated in			// the example at https://go.dev/play/p/XNtuhwdyu8Y for your reference.			// So the well known type google.protobuf.Duration needs a string.			//			// Please note that JSON schemas duration format is NOT the same, as that uses			// a different syntax starting with "P", supports daylight saving times and other			// different features, so it is NOT compatible.			Schema: &v3.Schema{				Type:        "string",				Pattern:     `^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$`,				Description: "Represents a a duration between -315,576,000,000s and 315,576,000,000s (around 10000 years). Precision is in nanoseconds. 1 nanosecond is represented as 0.000000001s",			},		},	}}// google.type.Date is serialized as a stringfunc NewGoogleTypeDateSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string", Format: "date"}}}}// google.type.DateTime is serialized as a stringfunc NewGoogleTypeDateTimeSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string", Format: "date-time"}}}}// google.protobuf.FieldMask masks is serialized as a stringfunc NewGoogleProtobufFieldMaskSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "string", Format: "field-mask"}}}}// google.protobuf.Struct is equivalent to a JSON objectfunc NewGoogleProtobufStructSchema() *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "object"}}}}// google.protobuf.Value is handled specially// See here for the details on the JSON mapping:////	https://developers.google.com/protocol-buffers/docs/proto3#json//// and here:////	https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Valuefunc NewGoogleProtobufValueSchema(name string) *v3.NamedSchemaOrReference {	return &v3.NamedSchemaOrReference{		Name: name,		Value: &v3.SchemaOrReference{			Oneof: &v3.SchemaOrReference_Schema{				Schema: &v3.Schema{					Description: "Represents a dynamically typed value which can be either null, a number, a string, a boolean, a recursive struct value, or a list of values.",				},			},		},	}}// google.protobuf.Any is handled specially// See here for the details on the JSON mapping:////	https://developers.google.com/protocol-buffers/docs/proto3#jsonfunc NewGoogleProtobufAnySchema(name string) *v3.NamedSchemaOrReference {	return &v3.NamedSchemaOrReference{		Name: name,		Value: &v3.SchemaOrReference{			Oneof: &v3.SchemaOrReference_Schema{				Schema: &v3.Schema{					Type:        "object",					Description: "Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.",					Properties: &v3.Properties{						AdditionalProperties: []*v3.NamedSchemaOrReference{							{								Name: "@type",								Value: &v3.SchemaOrReference{									Oneof: &v3.SchemaOrReference_Schema{										Schema: &v3.Schema{											Type:        "string",											Description: "The type of the serialized message.",										},									},								},							},						},					},					AdditionalProperties: &v3.AdditionalPropertiesItem{						Oneof: &v3.AdditionalPropertiesItem_Boolean{							Boolean: true,						},					},				},			},		},	}}// google.rpc.Status is handled speciallyfunc NewGoogleRpcStatusSchema(name string, any_name string) *v3.NamedSchemaOrReference {	return &v3.NamedSchemaOrReference{		Name: name,		Value: &v3.SchemaOrReference{			Oneof: &v3.SchemaOrReference_Schema{				Schema: &v3.Schema{					Type:        "object",					Description: "The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).",					Properties: &v3.Properties{						AdditionalProperties: []*v3.NamedSchemaOrReference{							{								Name: "code",								Value: &v3.SchemaOrReference{									Oneof: &v3.SchemaOrReference_Schema{										Schema: &v3.Schema{											Type:        "integer",											Format:      "int32",											Description: "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].",										},									},								},							},							{								Name: "message",								Value: &v3.SchemaOrReference{									Oneof: &v3.SchemaOrReference_Schema{										Schema: &v3.Schema{											Type:        "string",											Description: "A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.",										},									},								},							},							{								Name: "details",								Value: &v3.SchemaOrReference{									Oneof: &v3.SchemaOrReference_Schema{										Schema: &v3.Schema{											Type: "array",											Items: &v3.ItemsItem{												SchemaOrReference: []*v3.SchemaOrReference{													{														Oneof: &v3.SchemaOrReference_Reference{															Reference: &v3.Reference{																XRef: "#/components/schemas/" + any_name,															},														},													},												},											},											Description: "A list of messages that carry the error details.  There is a common set of message types for APIs to use.",										},									},								},							},						},					},				},			},		},	}}func NewGoogleProtobufMapFieldEntrySchema(value_field_schema *v3.SchemaOrReference) *v3.SchemaOrReference {	return &v3.SchemaOrReference{		Oneof: &v3.SchemaOrReference_Schema{			Schema: &v3.Schema{Type: "object",				AdditionalProperties: &v3.AdditionalPropertiesItem{					Oneof: &v3.AdditionalPropertiesItem_SchemaOrReference{						SchemaOrReference: value_field_schema,					},				},			},		},	}}
 |