Documentation
¶
Overview ¶
Package annotations provides shared annotation parsing for all sebuf protoc plugins.
This package extracts HTTP configuration, headers, query parameters, unwrap annotations, field examples, path parameters, and helper utilities from protobuf definitions. All four generators (httpgen, clientgen, tsclientgen, openapiv3) import this package instead of maintaining their own duplicated annotation parsing code.
Convention-based extensibility ¶
Each annotation concept lives in its own file with standardized function signatures:
- http_config.go: GetMethodHTTPConfig, GetServiceBasePath
- headers.go: GetServiceHeaders, GetMethodHeaders, CombineHeaders
- query.go: GetQueryParams
- unwrap.go: HasUnwrapAnnotation, GetUnwrapField, FindUnwrapField, IsRootUnwrap
- field_examples.go: GetFieldExamples
- path.go: ExtractPathParams, BuildHTTPPath, EnsureLeadingSlash
- method.go: HTTPMethodToString, HTTPMethodToLower
- helpers.go: LowerFirst
To add a new annotation type, create a new file following this pattern:
- Define any needed structs with exported fields.
- Add GetXxx() or ParseXxx() functions that accept protogen types.
- Use proto.GetExtension to extract the annotation from options.
Index ¶
- func BuildHTTPPath(servicePath, methodPath string) string
- func CombineHeaders(serviceHeaders, methodHeaders []*http.Header) []*http.Header
- func EnsureLeadingSlash(path string) string
- func ExtractPathParams(path string) []string
- func FindUnwrapField(message *protogen.Message) *protogen.Field
- func GetBytesEncoding(field *protogen.Field) http.BytesEncoding
- func GetEmptyBehavior(field *protogen.Field) http.EmptyBehavior
- func GetEnumEncoding(field *protogen.Field) http.EnumEncoding
- func GetEnumValueMapping(value *protogen.EnumValue) string
- func GetFieldExamples(field *protogen.Field) []string
- func GetFlattenPrefix(field *protogen.Field) string
- func GetInt64Encoding(field *protogen.Field) http.Int64Encoding
- func GetMethodHeaders(method *protogen.Method) []*http.Header
- func GetOneofConfig(oneof *protogen.Oneof) *http.OneofConfig
- func GetOneofVariantValue(field *protogen.Field) string
- func GetServiceBasePath(service *protogen.Service) string
- func GetServiceHeaders(service *protogen.Service) []*http.Header
- func GetTimestampFormat(field *protogen.Field) http.TimestampFormat
- func HTTPMethodToLower(m http.HttpMethod) string
- func HTTPMethodToString(m http.HttpMethod) string
- func HasAnyEnumValueMapping(enum *protogen.Enum) bool
- func HasBytesEncodingAnnotation(field *protogen.Field) bool
- func HasConflictingEnumAnnotations(field *protogen.Field) bool
- func HasEmptyBehaviorAnnotation(field *protogen.Field) bool
- func HasFlattenFields(message *protogen.Message) bool
- func HasOneofDiscriminator(message *protogen.Message) bool
- func HasTimestampFormatAnnotation(field *protogen.Field) bool
- func HasUnwrapAnnotation(field *protogen.Field) bool
- func IsFlattenField(field *protogen.Field) bool
- func IsInt64NumberEncoding(field *protogen.Field) bool
- func IsNullableField(field *protogen.Field) bool
- func IsRootUnwrap(message *protogen.Message) bool
- func IsTimestampField(field *protogen.Field) bool
- func LowerFirst(s string) string
- func ValidateBytesEncodingAnnotation(field *protogen.Field, messageName string) error
- func ValidateEmptyBehaviorAnnotation(field *protogen.Field, messageName string) error
- func ValidateFlattenCollisions(message *protogen.Message) error
- func ValidateFlattenField(field *protogen.Field, messageName string) error
- func ValidateNullableAnnotation(field *protogen.Field, messageName string) error
- func ValidateOneofDiscriminator(message *protogen.Message, oneof *protogen.Oneof, config *http.OneofConfig) error
- func ValidateTimestampFormatAnnotation(field *protogen.Field, messageName string) error
- type BytesEncodingValidationError
- type EmptyBehaviorValidationError
- type HTTPConfig
- type NullableValidationError
- type OneofDiscriminatorInfo
- type OneofVariant
- type QueryParam
- type ServiceConfig
- type TimestampFormatValidationError
- type UnwrapFieldInfo
- type UnwrapValidationError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildHTTPPath ¶
BuildHTTPPath combines service base path with method path. Handles slash normalization between the two path segments.
func CombineHeaders ¶
CombineHeaders merges service headers with method headers, with method headers taking precedence. The result is sorted by header name for deterministic output. Headers with empty names are skipped.
func EnsureLeadingSlash ¶
EnsureLeadingSlash ensures a path starts with "/".
func ExtractPathParams ¶
ExtractPathParams parses path variables from a path string. Example: "/users/{user_id}/posts/{post_id}" -> ["user_id", "post_id"].
func FindUnwrapField ¶
FindUnwrapField returns the unwrap-annotated repeated field in a message, or nil. This is the simple version without validation, used by tsclientgen and openapiv3 when only the repeated unwrap field is needed (not maps or root unwrap).
func GetBytesEncoding ¶ added in v0.7.0
func GetBytesEncoding(field *protogen.Field) http.BytesEncoding
GetBytesEncoding returns the bytes encoding for a field. Returns BYTES_ENCODING_UNSPECIFIED if not set (callers should use protojson default: BASE64).
func GetEmptyBehavior ¶
func GetEmptyBehavior(field *protogen.Field) http.EmptyBehavior
GetEmptyBehavior returns the empty behavior for a field. Returns EMPTY_BEHAVIOR_UNSPECIFIED if not set (callers should treat as PRESERVE).
func GetEnumEncoding ¶
func GetEnumEncoding(field *protogen.Field) http.EnumEncoding
GetEnumEncoding returns the enum encoding for a field. Returns ENUM_ENCODING_UNSPECIFIED if not set (callers should use protojson default: STRING names). This annotation is only valid on enum fields.
func GetEnumValueMapping ¶
GetEnumValueMapping returns the custom JSON value for an enum value, or empty string if not set. When set, this value should be used instead of the proto name for JSON serialization.
func GetFieldExamples ¶
GetFieldExamples extracts example values from field options. Returns nil if no field examples annotation is present.
func GetFlattenPrefix ¶ added in v0.7.0
GetFlattenPrefix returns the flatten prefix for a field, or empty string if not set.
func GetInt64Encoding ¶
func GetInt64Encoding(field *protogen.Field) http.Int64Encoding
GetInt64Encoding returns the int64 encoding for a field. Returns INT64_ENCODING_UNSPECIFIED if not set (callers should use protojson default: STRING). This annotation is valid on int64, sint64, sfixed64, uint64, and fixed64 fields.
func GetMethodHeaders ¶
GetMethodHeaders extracts header configuration from method options. Returns nil if no method headers annotation is present.
func GetOneofConfig ¶ added in v0.7.0
func GetOneofConfig(oneof *protogen.Oneof) *http.OneofConfig
GetOneofConfig returns the OneofConfig for a oneof, or nil if not annotated. Returns nil if discriminator is empty (annotation is treated as absent).
func GetOneofVariantValue ¶ added in v0.7.0
GetOneofVariantValue returns the custom discriminator value for a oneof variant field. Returns empty string if not set (caller should use the proto field name as default).
func GetServiceBasePath ¶
GetServiceBasePath extracts the base path from service options. Returns an empty string if no service config annotation is present.
func GetServiceHeaders ¶
GetServiceHeaders extracts header configuration from service options. Returns nil if no service headers annotation is present.
func GetTimestampFormat ¶ added in v0.7.0
func GetTimestampFormat(field *protogen.Field) http.TimestampFormat
GetTimestampFormat returns the timestamp format for a field. Returns TIMESTAMP_FORMAT_UNSPECIFIED if not set (callers should use protojson default: RFC3339).
func HTTPMethodToLower ¶
func HTTPMethodToLower(m http.HttpMethod) string
HTTPMethodToLower converts HttpMethod enum to a lowercase string. Returns "post" for unspecified or unknown values (backward compatibility). Used by OpenAPI generator which requires lowercase method names.
func HTTPMethodToString ¶
func HTTPMethodToString(m http.HttpMethod) string
HTTPMethodToString converts HttpMethod enum to an uppercase string. Returns "POST" for unspecified or unknown values (backward compatibility).
func HasAnyEnumValueMapping ¶
HasAnyEnumValueMapping returns true if any value in the enum has a custom JSON mapping.
func HasBytesEncodingAnnotation ¶ added in v0.7.0
HasBytesEncodingAnnotation returns true if the field has any non-default bytes_encoding. Returns false for UNSPECIFIED and BASE64 (both use protojson default behavior).
func HasConflictingEnumAnnotations ¶
HasConflictingEnumAnnotations checks if a field has both enum_encoding=NUMBER and enum_value annotations on its enum values, which is an error per CONTEXT.md.
func HasEmptyBehaviorAnnotation ¶
HasEmptyBehaviorAnnotation returns true if the field has any empty_behavior annotation set (including explicit PRESERVE, NULL, or OMIT - not just UNSPECIFIED).
func HasFlattenFields ¶ added in v0.7.0
HasFlattenFields returns true if any field in the message has a flatten annotation.
func HasOneofDiscriminator ¶ added in v0.7.0
HasOneofDiscriminator returns true if ANY oneof in the message has a discriminator annotation.
func HasTimestampFormatAnnotation ¶ added in v0.7.0
HasTimestampFormatAnnotation returns true if the field has any non-default timestamp_format. Returns false for UNSPECIFIED and RFC3339 (both use protojson default behavior).
func HasUnwrapAnnotation ¶
HasUnwrapAnnotation checks if a field has the unwrap=true annotation.
func IsFlattenField ¶ added in v0.7.0
IsFlattenField returns true if the field has flatten=true annotation.
func IsInt64NumberEncoding ¶
IsInt64NumberEncoding returns true if the field should encode int64/uint64 as JSON number. Returns false for UNSPECIFIED or STRING (both use protojson default string encoding).
func IsNullableField ¶
IsNullableField returns true if the field has nullable=true annotation.
func IsRootUnwrap ¶
IsRootUnwrap checks if a message has a single field with unwrap=true. A root unwrap means the entire message serializes as just the field's value.
func IsTimestampField ¶ added in v0.7.0
IsTimestampField returns true if the field is a google.protobuf.Timestamp message type.
func ValidateBytesEncodingAnnotation ¶ added in v0.7.0
ValidateBytesEncodingAnnotation checks if bytes_encoding is valid for a field. Returns error if used on non-bytes fields.
func ValidateEmptyBehaviorAnnotation ¶
ValidateEmptyBehaviorAnnotation checks if empty_behavior annotation is valid for a field. Returns error if used on primitive, repeated, or map fields.
func ValidateFlattenCollisions ¶ added in v0.7.0
ValidateFlattenCollisions checks for field name collisions when multiple fields are flattened at the same level.
func ValidateFlattenField ¶ added in v0.7.0
ValidateFlattenField validates that flatten is used correctly on a field. Returns error if flatten is used on repeated, map, scalar, or oneof variant fields. Also returns error if flatten_prefix is set without flatten=true.
func ValidateNullableAnnotation ¶
ValidateNullableAnnotation checks if nullable annotation is valid for a field. Returns error if nullable=true on a non-optional field or on a message field.
func ValidateOneofDiscriminator ¶ added in v0.7.0
func ValidateOneofDiscriminator( message *protogen.Message, oneof *protogen.Oneof, config *http.OneofConfig, ) error
ValidateOneofDiscriminator validates a oneof with discriminator annotation. Checks for: 1. Discriminator name collisions with parent message fields 2. When flatten=true: all variants must be message types 3. When flatten=true: variant child field names must not collide with parent fields or discriminator.
Types ¶
type BytesEncodingValidationError ¶ added in v0.7.0
BytesEncodingValidationError represents an error in bytes_encoding annotation validation.
func (*BytesEncodingValidationError) Error ¶ added in v0.7.0
func (e *BytesEncodingValidationError) Error() string
type EmptyBehaviorValidationError ¶
EmptyBehaviorValidationError represents an error in empty_behavior annotation validation.
func (*EmptyBehaviorValidationError) Error ¶
func (e *EmptyBehaviorValidationError) Error() string
type HTTPConfig ¶
type HTTPConfig struct {
Path string
Method string // "GET", "POST", "PUT", "DELETE", "PATCH"
PathParams []string // Path variable names extracted from path
Stream bool // When true, this method uses SSE streaming
}
HTTPConfig represents the HTTP configuration for a method.
func GetMethodHTTPConfig ¶
func GetMethodHTTPConfig(method *protogen.Method) *HTTPConfig
GetMethodHTTPConfig extracts HTTP configuration from method options. Returns nil if no HTTP config annotation is present.
type NullableValidationError ¶
NullableValidationError represents an error in nullable annotation validation.
func (*NullableValidationError) Error ¶
func (e *NullableValidationError) Error() string
type OneofDiscriminatorInfo ¶ added in v0.7.0
type OneofDiscriminatorInfo struct {
Oneof *protogen.Oneof
Discriminator string // JSON field name for discriminator (e.g., "type")
Flatten bool // Whether to flatten variant fields to parent level
Variants []OneofVariant // Resolved variant info
}
OneofDiscriminatorInfo holds parsed oneof discriminator configuration for a single oneof.
func GetOneofDiscriminatorInfo ¶ added in v0.7.0
func GetOneofDiscriminatorInfo(oneof *protogen.Oneof) *OneofDiscriminatorInfo
GetOneofDiscriminatorInfo resolves the full discriminator info for a oneof. Returns nil if the oneof has no oneof_config annotation. For each variant, uses oneof_value if set, otherwise proto field name.
type OneofVariant ¶ added in v0.7.0
type OneofVariant struct {
Field *protogen.Field
DiscriminatorVal string // Value for this variant in the discriminator field
IsMessage bool // Whether variant is a message type (required for flatten)
}
OneofVariant holds information about a single oneof variant.
type QueryParam ¶
type QueryParam struct {
FieldName string // Proto field name (e.g., "page_number")
FieldGoName string // Go field name (e.g., "PageNumber")
FieldJSONName string // JSON field name / camelCase (e.g., "pageNumber")
ParamName string // Query parameter name (e.g., "page")
Required bool // Whether the parameter is required
FieldKind string // Proto field kind (e.g., "string", "int32", "bool")
Field *protogen.Field // Raw protogen field reference
}
QueryParam represents a query parameter configuration extracted from a field. This is the unified struct containing all fields needed by all 4 generators.
func GetQueryParams ¶
func GetQueryParams(message *protogen.Message) []QueryParam
GetQueryParams extracts query parameter configurations from message fields. Returns all fields that have the sebuf.http.query annotation.
type ServiceConfig ¶
type ServiceConfig struct {
BasePath string
}
ServiceConfig represents the HTTP configuration for a service.
type TimestampFormatValidationError ¶ added in v0.7.0
TimestampFormatValidationError represents an error in timestamp_format annotation validation.
func (*TimestampFormatValidationError) Error ¶ added in v0.7.0
func (e *TimestampFormatValidationError) Error() string
type UnwrapFieldInfo ¶
type UnwrapFieldInfo struct {
Field *protogen.Field // The field with unwrap=true
ElementType *protogen.Message // The element type of the repeated field (if message type)
IsRootUnwrap bool // True if this is a root-level unwrap (single field in message)
IsMapField bool // True if the unwrap field is a map (only for root unwrap)
}
UnwrapFieldInfo contains information about an unwrap field in a message.
func GetUnwrapField ¶
func GetUnwrapField(message *protogen.Message) (*UnwrapFieldInfo, error)
GetUnwrapField returns the unwrap field info for a message, or nil if none exists. Returns an error if the annotation is invalid (e.g., on non-repeated/non-map field, multiple unwrap fields, or map-without-root-unwrap).
Root-level unwrap: When a message has exactly one field with unwrap=true on a map or repeated field, the entire message serializes to just that field's value.
Map-value unwrap: When a repeated field has unwrap=true and the message is used as a map value, the wrapper is collapsed to just the array.
type UnwrapValidationError ¶
UnwrapValidationError represents an error in unwrap annotation validation.
func (*UnwrapValidationError) Error ¶
func (e *UnwrapValidationError) Error() string