annotations

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2026 License: MIT Imports: 9 Imported by: 0

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:

  1. Define any needed structs with exported fields.
  2. Add GetXxx() or ParseXxx() functions that accept protogen types.
  3. Use proto.GetExtension to extract the annotation from options.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildHTTPPath

func BuildHTTPPath(servicePath, methodPath string) string

BuildHTTPPath combines service base path with method path. Handles slash normalization between the two path segments.

func CombineHeaders

func CombineHeaders(serviceHeaders, methodHeaders []*http.Header) []*http.Header

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

func EnsureLeadingSlash(path string) string

EnsureLeadingSlash ensures a path starts with "/".

func ExtractPathParams

func ExtractPathParams(path string) []string

ExtractPathParams parses path variables from a path string. Example: "/users/{user_id}/posts/{post_id}" -> ["user_id", "post_id"].

func FindUnwrapField

func FindUnwrapField(message *protogen.Message) *protogen.Field

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

func GetEnumValueMapping(value *protogen.EnumValue) string

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

func GetFieldExamples(field *protogen.Field) []string

GetFieldExamples extracts example values from field options. Returns nil if no field examples annotation is present.

func GetFlattenPrefix added in v0.7.0

func GetFlattenPrefix(field *protogen.Field) string

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

func GetMethodHeaders(method *protogen.Method) []*http.Header

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

func GetOneofVariantValue(field *protogen.Field) string

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

func GetServiceBasePath(service *protogen.Service) string

GetServiceBasePath extracts the base path from service options. Returns an empty string if no service config annotation is present.

func GetServiceHeaders

func GetServiceHeaders(service *protogen.Service) []*http.Header

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

func HasAnyEnumValueMapping(enum *protogen.Enum) bool

HasAnyEnumValueMapping returns true if any value in the enum has a custom JSON mapping.

func HasBytesEncodingAnnotation added in v0.7.0

func HasBytesEncodingAnnotation(field *protogen.Field) bool

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

func HasConflictingEnumAnnotations(field *protogen.Field) bool

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

func HasEmptyBehaviorAnnotation(field *protogen.Field) bool

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

func HasFlattenFields(message *protogen.Message) bool

HasFlattenFields returns true if any field in the message has a flatten annotation.

func HasOneofDiscriminator added in v0.7.0

func HasOneofDiscriminator(message *protogen.Message) bool

HasOneofDiscriminator returns true if ANY oneof in the message has a discriminator annotation.

func HasTimestampFormatAnnotation added in v0.7.0

func HasTimestampFormatAnnotation(field *protogen.Field) bool

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

func HasUnwrapAnnotation(field *protogen.Field) bool

HasUnwrapAnnotation checks if a field has the unwrap=true annotation.

func IsFlattenField added in v0.7.0

func IsFlattenField(field *protogen.Field) bool

IsFlattenField returns true if the field has flatten=true annotation.

func IsInt64NumberEncoding

func IsInt64NumberEncoding(field *protogen.Field) bool

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

func IsNullableField(field *protogen.Field) bool

IsNullableField returns true if the field has nullable=true annotation.

func IsRootUnwrap

func IsRootUnwrap(message *protogen.Message) bool

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

func IsTimestampField(field *protogen.Field) bool

IsTimestampField returns true if the field is a google.protobuf.Timestamp message type.

func LowerFirst

func LowerFirst(s string) string

LowerFirst converts "FooBar" to "fooBar".

func ValidateBytesEncodingAnnotation added in v0.7.0

func ValidateBytesEncodingAnnotation(field *protogen.Field, messageName string) error

ValidateBytesEncodingAnnotation checks if bytes_encoding is valid for a field. Returns error if used on non-bytes fields.

func ValidateEmptyBehaviorAnnotation

func ValidateEmptyBehaviorAnnotation(field *protogen.Field, messageName string) error

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

func ValidateFlattenCollisions(message *protogen.Message) error

ValidateFlattenCollisions checks for field name collisions when multiple fields are flattened at the same level.

func ValidateFlattenField added in v0.7.0

func ValidateFlattenField(field *protogen.Field, messageName string) error

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

func ValidateNullableAnnotation(field *protogen.Field, messageName string) error

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.

func ValidateTimestampFormatAnnotation added in v0.7.0

func ValidateTimestampFormatAnnotation(field *protogen.Field, messageName string) error

ValidateTimestampFormatAnnotation checks if timestamp_format is valid for a field. Returns error if used on non-Timestamp fields.

Types

type BytesEncodingValidationError added in v0.7.0

type BytesEncodingValidationError struct {
	MessageName string
	FieldName   string
	Reason      string
}

BytesEncodingValidationError represents an error in bytes_encoding annotation validation.

func (*BytesEncodingValidationError) Error added in v0.7.0

type EmptyBehaviorValidationError

type EmptyBehaviorValidationError struct {
	MessageName string
	FieldName   string
	Reason      string
}

EmptyBehaviorValidationError represents an error in empty_behavior annotation validation.

func (*EmptyBehaviorValidationError) Error

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

type NullableValidationError struct {
	MessageName string
	FieldName   string
	Reason      string
}

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

type TimestampFormatValidationError struct {
	MessageName string
	FieldName   string
	Reason      string
}

TimestampFormatValidationError represents an error in timestamp_format annotation validation.

func (*TimestampFormatValidationError) Error added in v0.7.0

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

type UnwrapValidationError struct {
	MessageName string
	FieldName   string
	Reason      string
}

UnwrapValidationError represents an error in unwrap annotation validation.

func (*UnwrapValidationError) Error

func (e *UnwrapValidationError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL