diff --git a/CHANGELOG.md b/CHANGELOG.md index c21cf747..99090f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,45 @@ The format is based on [Keep a Changelog], and this project adheres to [semantic versioning]: https://semver.org/spec/v2.0.0.html [bc]: https://github.com/dogmatiq/.github/blob/main/VERSIONING.md#changelogs +## [Unreleased] + +This release moves Dogma's Protocol Buffers schema to the +[`github.com/dogmatiq/protobuf`] module. The `uuidpb`, `identitypb`, +`envelopepb` and `messaginggrpc` packages are now provided by that module, and +`configpb` is regenerated to import its types. + +The schema in `github.com/dogmatiq/protobuf` uses the `dogma.protobuf.v1` +Protocol Buffers package instead of `dogma.protobuf`, so the full names of +these messages and their `google.protobuf.Any` type URLs have changed. Their +binary encoding is unchanged. + +### Added + +- Added the `envelope` package, which contains `Packer`, `EffectPacker`, + `Unpack()` and the packing options previously in `envelopepb`. +- Added the `uuidcollection` package, which contains `Map`, `Set` and + `NewSet()` previously in `uuidpb`. + +### Changed + +- **[BC]** `envelope.WithExtension()` and `WithBaggage()` now panic if the + value is a nil pointer, such as `(*wrapperspb.StringValue)(nil)`. Previously, + it was packed as an empty message. + +### Removed + +- **[BC]** Removed the `protobuf/uuidpb`, `protobuf/identitypb` and + `protobuf/envelopepb` packages. Use the packages of the same name in + `github.com/dogmatiq/protobuf` instead. +- **[BC]** Removed the `grpc/messaginggrpc` package. Use the package of the same + name in `github.com/dogmatiq/protobuf` instead. +- **[BC]** Removed `CommandExecutorAPI` and the `UnrecognizedApplication`, + `UnrecognizedCommandType`, `UnrecognizedEventType`, `MalformedMessage` and + `InvalidMessage` error details, along with their error constructors. They're + expected in a future version of `github.com/dogmatiq/protobuf`. + +[`github.com/dogmatiq/protobuf`]: https://github.com/dogmatiq/protobuf + ## [0.28.0] - 2026-11-02 ### Added diff --git a/config/aggregate.go b/config/aggregate.go index a2a0aa67..de75f9c0 100644 --- a/config/aggregate.go +++ b/config/aggregate.go @@ -3,7 +3,7 @@ package config import ( "github.com/dogmatiq/dogma" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/identitypb" + "github.com/dogmatiq/protobuf/identitypb" ) // Aggregate is a [Handler] that represents the configuration of a diff --git a/config/application.go b/config/application.go index 4a17105e..8c385399 100644 --- a/config/application.go +++ b/config/application.go @@ -6,8 +6,8 @@ import ( "github.com/dogmatiq/dogma" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" ) // Application is an [Entity] that represents the configuration of a diff --git a/config/entity.go b/config/entity.go index 8ec169fa..9eda2f8d 100644 --- a/config/entity.go +++ b/config/entity.go @@ -7,8 +7,8 @@ import ( "github.com/dogmatiq/enginekit/internal/typename" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" ) // An Entity is a [Component] that that represents the configuration of a Dogma diff --git a/config/entity_test.go b/config/entity_test.go index 77f1938f..3f7ee5f8 100644 --- a/config/entity_test.go +++ b/config/entity_test.go @@ -8,8 +8,8 @@ import ( "github.com/dogmatiq/enginekit/config/internal/configbuilder" "github.com/dogmatiq/enginekit/config/internal/constraints" "github.com/dogmatiq/enginekit/internal/test" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" ) func testEntity[ diff --git a/config/identity.go b/config/identity.go index d55103bd..468c8e18 100644 --- a/config/identity.go +++ b/config/identity.go @@ -7,7 +7,7 @@ import ( "unicode" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/uuidpb" ) // Identity is a [Component] that that represents the unique identity of an diff --git a/config/integration.go b/config/integration.go index 4b50d0b4..92af2efb 100644 --- a/config/integration.go +++ b/config/integration.go @@ -3,7 +3,7 @@ package config import ( "github.com/dogmatiq/dogma" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/identitypb" + "github.com/dogmatiq/protobuf/identitypb" ) // Integration is a [Handler] that represents the configuration of a diff --git a/config/process.go b/config/process.go index 9cf5f493..bee1b75f 100644 --- a/config/process.go +++ b/config/process.go @@ -3,7 +3,7 @@ package config import ( "github.com/dogmatiq/dogma" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/identitypb" + "github.com/dogmatiq/protobuf/identitypb" ) // Process is a [Handler] that represents the configuration of a diff --git a/config/projection.go b/config/projection.go index 397e7d39..e5c50702 100644 --- a/config/projection.go +++ b/config/projection.go @@ -3,7 +3,7 @@ package config import ( "github.com/dogmatiq/dogma" "github.com/dogmatiq/enginekit/optional" - "github.com/dogmatiq/enginekit/protobuf/identitypb" + "github.com/dogmatiq/protobuf/identitypb" ) // Projection is a [Handler] that represents the configuration of a diff --git a/enginetest/stubs/message.go b/enginetest/stubs/message.go index e4c4068d..1393da3e 100644 --- a/enginetest/stubs/message.go +++ b/enginetest/stubs/message.go @@ -8,7 +8,7 @@ import ( "regexp" "github.com/dogmatiq/dogma" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/uuidpb" ) // CommandStub is a test implementation of [dogma.Command]. diff --git a/enginetest/stubs/uuid.go b/enginetest/stubs/uuid.go index fb43f2e4..4f7b6ad8 100644 --- a/enginetest/stubs/uuid.go +++ b/enginetest/stubs/uuid.go @@ -4,7 +4,7 @@ import ( "strconv" "sync/atomic" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/uuidpb" ) // UUIDSequence is a generator of deterministic UUIDs for use in tests. diff --git a/envelope/any.go b/envelope/any.go new file mode 100644 index 00000000..67efa4f3 --- /dev/null +++ b/envelope/any.go @@ -0,0 +1,19 @@ +package envelope + +import ( + "github.com/dogmatiq/protobuf/envelopepb" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" +) + +// packAsAny returns x as an [*anypb.Any], panicking if it is nil or cannot be +// packed. +// +// Options pack their value when they are created, rather than when they are +// applied, so that an invalid value is reported where the option is created and +// is packed only once. +func packAsAny(x proto.Message) *anypb.Any { + body := &envelopepb.Body{} + envelopepb.SetExtension(body, x) + return body.GetExtensions()[0] +} diff --git a/envelope/doc.go b/envelope/doc.go new file mode 100644 index 00000000..db1b75b2 --- /dev/null +++ b/envelope/doc.go @@ -0,0 +1,2 @@ +// Package envelope packs Dogma messages into envelopes and unpacks them again. +package envelope diff --git a/protobuf/envelopepb/effectpacker.go b/envelope/effectpacker.go similarity index 76% rename from protobuf/envelopepb/effectpacker.go rename to envelope/effectpacker.go index 565b3e42..83bc05f3 100644 --- a/protobuf/envelopepb/effectpacker.go +++ b/envelope/effectpacker.go @@ -1,28 +1,29 @@ -package envelopepb +package envelope import ( "fmt" "github.com/dogmatiq/dogma" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/envelopepb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" "google.golang.org/protobuf/types/known/timestamppb" ) // An EffectPacker packs messages produced while handling a specific causal -// message into a [MultiEnvelope]. +// message into a [envelopepb.MultiEnvelope]. type EffectPacker struct { generateID func() *uuidpb.UUID now func() *timestamppb.Timestamp - header *Header - bodies []*Body + header *envelopepb.Header + bodies []*envelopepb.Body sealed bool } // PackEffects returns an [EffectPacker] that packs messages produced by h while // handling cause. func (p *Packer) PackEffects( - cause *Envelope, + cause *envelopepb.Envelope, h *identitypb.Identity, options ...PackEffectsOption, ) *EffectPacker { @@ -51,10 +52,10 @@ func (p *Packer) PackEffects( } } - header := NewHeaderBuilder(). + header := envelopepb.NewHeaderBuilder(). WithCausationId(cause.GetBody().GetMessageId()). WithCorrelationId(cause.GetHeader().GetCorrelationId()). - WithSource(NewSourceBuilder(). + WithSource(envelopepb.NewSourceBuilder(). WithSite(p.Site). WithApplication(p.Application). WithHandler(h). @@ -69,7 +70,7 @@ func (p *Packer) PackEffects( opt.applyPackEffectsOption(header) } - if err := header.validate(); err != nil { + if err := header.Validate(); err != nil { panic(fmt.Errorf("invalid header: %w", err)) } @@ -81,26 +82,26 @@ func (p *Packer) PackEffects( } // PackCommand appends m to the multi-envelope under construction. -func (p *EffectPacker) PackCommand(m dogma.Command, options ...PackEffectCommandOption) *Envelope { +func (p *EffectPacker) PackCommand(m dogma.Command, options ...PackEffectCommandOption) *envelopepb.Envelope { return packEffectBody(p, m, PackEffectCommandOption.applyPackEffectCommandOption, options...) } // PackEvent appends m to the multi-envelope under construction. -func (p *EffectPacker) PackEvent(m dogma.Event, options ...PackEffectEventOption) *Envelope { +func (p *EffectPacker) PackEvent(m dogma.Event, options ...PackEffectEventOption) *envelopepb.Envelope { return packEffectBody(p, m, PackEffectEventOption.applyPackEffectEventOption, options...) } // PackDeadline appends m to the multi-envelope under construction. -func (p *EffectPacker) PackDeadline(m dogma.Deadline, options ...PackEffectDeadlineOption) *Envelope { +func (p *EffectPacker) PackDeadline(m dogma.Deadline, options ...PackEffectDeadlineOption) *envelopepb.Envelope { return packEffectBody(p, m, PackEffectDeadlineOption.applyPackEffectDeadlineOption, options...) } func packEffectBody[T any]( p *EffectPacker, m dogma.Message, - apply func(T, *Body), + apply func(T, *envelopepb.Body), options ...T, -) *Envelope { +) *envelopepb.Envelope { p.mustNotBeSealed() mt, ok := dogma.RegisteredMessageTypeOf(m) @@ -120,10 +121,10 @@ func packEffectBody[T any]( )) } - body := NewBodyBuilder(). + body := envelopepb.NewBodyBuilder(). WithMessageId(p.generateID()). WithMessage( - NewMessageBuilder(). + envelopepb.NewMessageBuilder(). WithTypeId(uuidpb.MustParse(mt.ID())). WithDescription(m.MessageDescription()). WithData(data). @@ -139,21 +140,21 @@ func packEffectBody[T any]( body.SetCreatedAt(p.now()) } - if err := body.validate(p.header); err != nil { + if err := body.Validate(p.header); err != nil { panic(fmt.Errorf("invalid body: %w", err)) } p.bodies = append(p.bodies, body) - return NewEnvelopeBuilder(). + return envelopepb.NewEnvelopeBuilder(). WithHeader(p.header). WithBody(body). Build() } -// Seal returns a [MultiEnvelope] containing all packed messages, or false if no -// messages were packed. -func (p *EffectPacker) Seal() (*MultiEnvelope, bool) { +// Seal returns a [envelopepb.MultiEnvelope] containing all packed messages, or +// false if no messages were packed. +func (p *EffectPacker) Seal() (*envelopepb.MultiEnvelope, bool) { p.mustNotBeSealed() p.sealed = true @@ -161,7 +162,7 @@ func (p *EffectPacker) Seal() (*MultiEnvelope, bool) { return nil, false } - return NewMultiEnvelopeBuilder(). + return envelopepb.NewMultiEnvelopeBuilder(). WithHeader(p.header). WithBodies(p.bodies). Build(), true diff --git a/protobuf/envelopepb/effectpacker_test.go b/envelope/effectpacker_test.go similarity index 99% rename from protobuf/envelopepb/effectpacker_test.go rename to envelope/effectpacker_test.go index 2740d68b..7f0d1d47 100644 --- a/protobuf/envelopepb/effectpacker_test.go +++ b/envelope/effectpacker_test.go @@ -1,14 +1,15 @@ -package envelopepb_test +package envelope_test import ( "testing" "time" . "github.com/dogmatiq/enginekit/enginetest/stubs" + . "github.com/dogmatiq/enginekit/envelope" . "github.com/dogmatiq/enginekit/internal/test" - . "github.com/dogmatiq/enginekit/protobuf/envelopepb" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + . "github.com/dogmatiq/protobuf/envelopepb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" anypb "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" diff --git a/protobuf/envelopepb/packer.go b/envelope/packer.go similarity index 74% rename from protobuf/envelopepb/packer.go rename to envelope/packer.go index 1b5e8865..0b8642b5 100644 --- a/protobuf/envelopepb/packer.go +++ b/envelope/packer.go @@ -1,4 +1,4 @@ -package envelopepb +package envelope import ( "fmt" @@ -7,8 +7,9 @@ import ( "time" "github.com/dogmatiq/dogma" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/envelopepb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/timestamppb" @@ -38,7 +39,7 @@ type Packer struct { } // PackCommand returns an envelope containing the given command. -func (p *Packer) PackCommand(m dogma.Command, options ...PackCommandOption) *Envelope { +func (p *Packer) PackCommand(m dogma.Command, options ...PackCommandOption) *envelopepb.Envelope { mt, ok := dogma.RegisteredMessageTypeOf(m) if !ok { panic(fmt.Sprintf( @@ -58,21 +59,21 @@ func (p *Packer) PackCommand(m dogma.Command, options ...PackCommandOption) *Env id := p.generateID() - env := NewEnvelopeBuilder(). + env := envelopepb.NewEnvelopeBuilder(). WithHeader( - NewHeaderBuilder(). + envelopepb.NewHeaderBuilder(). WithCausationId(id). WithCorrelationId(id). - WithSource(NewSourceBuilder(). + WithSource(envelopepb.NewSourceBuilder(). WithSite(p.Site). WithApplication(p.Application). Build()). Build(), ). WithBody( - NewBodyBuilder(). + envelopepb.NewBodyBuilder(). WithMessageId(id). - WithMessage(NewMessageBuilder(). + WithMessage(envelopepb.NewMessageBuilder(). WithTypeId(uuidpb.MustParse(mt.ID())). WithDescription(m.MessageDescription()). WithData(data). @@ -106,12 +107,12 @@ func (p *Packer) PackCommand(m dogma.Command, options ...PackCommandOption) *Env // // T may be a message interface such as [dogma.Command] or a concrete message // type. -func Unpack[T dogma.Message](env *Envelope) (T, error) { +func Unpack[T dogma.Message](env *envelopepb.Envelope) (T, error) { var zero T message := env.GetBody().GetMessage() - if err := message.validate(); err != nil { + if err := message.Validate(); err != nil { return zero, fmt.Errorf( "unable to unpack envelope as %s: %w", reflect.TypeFor[T](), @@ -173,57 +174,63 @@ func (p *Packer) generateID() *uuidpb.UUID { // PackCommandOption is an option that modifies the behavior of // [Packer.PackCommand]. type PackCommandOption interface { - applyPackCommandOption(*Envelope) + applyPackCommandOption(*envelopepb.Envelope) } // PackEffectsOption is an option that modifies the behavior of // [Packer.PackEffects]. type PackEffectsOption interface { - applyPackEffectsOption(*Header) + applyPackEffectsOption(*envelopepb.Header) } // PackEffectCommandOption is an option that modifies the behavior of // [EffectPacker.PackCommand]. type PackEffectCommandOption interface { - applyPackEffectCommandOption(*Body) + applyPackEffectCommandOption(*envelopepb.Body) } // PackEffectEventOption is an option that modifies the behavior of // [EffectPacker.PackEvent]. type PackEffectEventOption interface { - applyPackEffectEventOption(*Body) + applyPackEffectEventOption(*envelopepb.Body) } // PackEffectDeadlineOption is an option that modifies the behavior of // [EffectPacker.PackDeadline]. type PackEffectDeadlineOption interface { - applyPackEffectDeadlineOption(*Body) + applyPackEffectDeadlineOption(*envelopepb.Body) } type ( - packEffectsOption func(*Header) - packCommandOptionFunc func(*Body) - packEffectDeadlineOptionFunc func(*Body) + packEffectsOption func(*envelopepb.Header) + packCommandOptionFunc func(*envelopepb.Body) + packEffectDeadlineOptionFunc func(*envelopepb.Body) universalOption struct { - applyToBodyFunc func(*Body) - applyToHeaderFunc func(*Header) + applyToBodyFunc func(*envelopepb.Body) + applyToHeaderFunc func(*envelopepb.Header) } ) -func (o packEffectsOption) applyPackEffectsOption(header *Header) { o(header) } -func (o packCommandOptionFunc) applyPackCommandOption(env *Envelope) { o(env.GetBody()) } -func (o packEffectDeadlineOptionFunc) applyPackEffectDeadlineOption(body *Body) { o(body) } -func (o universalOption) applyPackCommandOption(env *Envelope) { o.applyToBodyFunc(env.GetBody()) } -func (o universalOption) applyPackEffectCommandOption(body *Body) { o.applyToBodyFunc(body) } -func (o universalOption) applyPackEffectEventOption(body *Body) { o.applyToBodyFunc(body) } -func (o universalOption) applyPackEffectDeadlineOption(body *Body) { o.applyToBodyFunc(body) } -func (o universalOption) applyPackEffectsOption(header *Header) { o.applyToHeaderFunc(header) } +func (o packEffectsOption) applyPackEffectsOption(header *envelopepb.Header) { o(header) } +func (o packCommandOptionFunc) applyPackCommandOption(env *envelopepb.Envelope) { o(env.GetBody()) } +func (o packEffectDeadlineOptionFunc) applyPackEffectDeadlineOption(body *envelopepb.Body) { o(body) } +func (o universalOption) applyPackCommandOption(env *envelopepb.Envelope) { + o.applyToBodyFunc(env.GetBody()) +} +func (o universalOption) applyPackEffectCommandOption(body *envelopepb.Body) { o.applyToBodyFunc(body) } +func (o universalOption) applyPackEffectEventOption(body *envelopepb.Body) { o.applyToBodyFunc(body) } +func (o universalOption) applyPackEffectDeadlineOption(body *envelopepb.Body) { + o.applyToBodyFunc(body) +} +func (o universalOption) applyPackEffectsOption(header *envelopepb.Header) { + o.applyToHeaderFunc(header) +} // WithIdempotencyKey sets the idempotency key of a command packed via // [Packer.PackCommand]. func WithIdempotencyKey(key string) PackCommandOption { return packCommandOptionFunc( - func(body *Body) { + func(body *envelopepb.Body) { body.SetIdempotencyKey(key) }, ) @@ -233,7 +240,7 @@ func WithIdempotencyKey(key string) PackCommandOption { // of messages packed via [Packer.PackEffects]. func WithInstanceID(id string) PackEffectsOption { return packEffectsOption( - func(header *Header) { + func(header *envelopepb.Header) { header.GetSource().SetInstanceId(id) }, ) @@ -243,7 +250,7 @@ func WithInstanceID(id string) PackEffectsOption { // via [EffectPacker.PackDeadline]. func WithScheduledFor(t time.Time) PackEffectDeadlineOption { return packEffectDeadlineOptionFunc( - func(body *Body) { + func(body *envelopepb.Body) { body.SetScheduledFor(timestamppb.New(t)) }, ) @@ -260,14 +267,14 @@ func WithExtension(x proto.Message) interface { PackEffectEventOption PackEffectDeadlineOption } { - v := marshalAsAny(x) + v := packAsAny(x) return universalOption{ - applyToBodyFunc: func(body *Body) { - body.SetExtensions(appendOrReplace(body.GetExtensions(), v)) + applyToBodyFunc: func(body *envelopepb.Body) { + envelopepb.SetExtension(body, v) }, - applyToHeaderFunc: func(header *Header) { - header.SetExtensions(appendOrReplace(header.GetExtensions(), v)) + applyToHeaderFunc: func(header *envelopepb.Header) { + envelopepb.SetExtension(header, v) }, } } @@ -283,20 +290,20 @@ func WithBaggage(x proto.Message) interface { PackEffectEventOption PackEffectDeadlineOption } { - v := marshalAsAny(x) + v := packAsAny(x) return universalOption{ - applyToBodyFunc: func(body *Body) { - body.SetBaggage(appendOrReplace(body.GetBaggage(), v)) + applyToBodyFunc: func(body *envelopepb.Body) { + envelopepb.SetBaggage(body, v) }, - applyToHeaderFunc: func(header *Header) { - header.SetBaggage(appendOrReplace(header.GetBaggage(), v)) + applyToHeaderFunc: func(header *envelopepb.Header) { + envelopepb.SetBaggage(header, v) }, } } -// flattenAnyValues merges two slices of [*anypb.Any] values from a [Header] and -// [Body] into a single slice. +// flattenAnyValues merges two slices of [*anypb.Any] values from a +// [envelopepb.Header] and [envelopepb.Body] into a single slice. // // Later values override earlier values with the same type URL, so body values // override header values and the last repeated value in either location wins. diff --git a/protobuf/envelopepb/packer_test.go b/envelope/packer_test.go similarity index 90% rename from protobuf/envelopepb/packer_test.go rename to envelope/packer_test.go index 33473d40..fb965218 100644 --- a/protobuf/envelopepb/packer_test.go +++ b/envelope/packer_test.go @@ -1,4 +1,4 @@ -package envelopepb_test +package envelope_test import ( "fmt" @@ -7,10 +7,11 @@ import ( "github.com/dogmatiq/dogma" . "github.com/dogmatiq/enginekit/enginetest/stubs" + . "github.com/dogmatiq/enginekit/envelope" . "github.com/dogmatiq/enginekit/internal/test" - . "github.com/dogmatiq/enginekit/protobuf/envelopepb" - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + . "github.com/dogmatiq/protobuf/envelopepb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" @@ -92,7 +93,7 @@ func TestPacker_PackAndUnpack(t *testing.T) { t.Run("it panics if passed an unregistered message", func(t *testing.T) { ExpectPanic( t, - "*envelopepb_test.T is not a registered message type", + "*envelope_test.T is not a registered message type", func() { type T struct{ dogma.Command } packer.PackCommand(&T{}) @@ -103,7 +104,7 @@ func TestPacker_PackAndUnpack(t *testing.T) { t.Run("it panics if the message cannot be marshaled", func(t *testing.T) { ExpectPanic( t, - "unable to marshal *envelopepb_test.T: json: unsupported type: func()", + "unable to marshal *envelope_test.T: json: unsupported type: func()", func() { type T struct{ CommandStub[func()] } dogma.RegisterCommand[*T]("622003a4-01a5-4c77-8a4c-cb36b51994e7") @@ -302,18 +303,25 @@ func TestWithExtension(t *testing.T) { WithExtension(nil) }, ) - }) - t.Run("it panics if x is an empty any", func(t *testing.T) { ExpectPanic( t, - "value must not be an empty google.protobuf.Any", + "value must not be nil", + func() { + WithExtension((*anypb.Any)(nil)) + }, + ) + + ExpectPanic( + t, + "value must not be nil", func() { - var x *anypb.Any - WithExtension(x) + WithExtension((*wrapperspb.StringValue)(nil)) }, ) + }) + t.Run("it panics if x is an empty any", func(t *testing.T) { ExpectPanic( t, "value must not be an empty google.protobuf.Any", @@ -354,38 +362,6 @@ func TestWithExtension(t *testing.T) { } }) - t.Run("it accepts typed nil messages", func(t *testing.T) { - packer := &Packer{ - Application: identitypb. - NewIdentityBuilder(). - WithName("app"). - WithKey(uuidpb.Generate()). - Build(), - } - - var value *wrapperspb.StringValue - got := packer.PackCommand(CommandA1, WithExtension(value)) - - if len(got.GetBody().GetExtensions()) != 1 { - t.Fatalf("unexpected extension count: got %d, want 1", len(got.GetBody().GetExtensions())) - } - - if got.GetBody().GetExtensions()[0].GetTypeUrl() != "type.googleapis.com/google.protobuf.StringValue" { - t.Fatalf( - "unexpected extension type URL: got %q, want %q", - got.GetBody().GetExtensions()[0].GetTypeUrl(), - "type.googleapis.com/google.protobuf.StringValue", - ) - } - - if len(got.GetBody().GetExtensions()[0].GetValue()) != 0 { - t.Fatalf( - "unexpected extension payload length: got %d, want 0", - len(got.GetBody().GetExtensions()[0].GetValue()), - ) - } - }) - t.Run("it adds x to the extensions", func(t *testing.T) { packer := &Packer{ Application: identitypb. @@ -487,6 +463,22 @@ func TestWithBaggage(t *testing.T) { WithBaggage(nil) }, ) + + ExpectPanic( + t, + "value must not be nil", + func() { + WithBaggage((*anypb.Any)(nil)) + }, + ) + + ExpectPanic( + t, + "value must not be nil", + func() { + WithBaggage((*wrapperspb.StringValue)(nil)) + }, + ) }) t.Run("it panics if x is an empty any", func(t *testing.T) { diff --git a/go.mod b/go.mod index 26a3cc0a..731a95e4 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/dogmatiq/enginekit go 1.27 require ( - github.com/dogmatiq/dapper v0.7.0 github.com/dogmatiq/dogma v0.25.0 github.com/dogmatiq/primo v0.4.4 + github.com/dogmatiq/protobuf v0.2.0 github.com/dogmatiq/spruce v0.2.4 github.com/google/go-cmp v0.7.0 go.opentelemetry.io/otel v1.47.0 @@ -22,7 +22,6 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dave/jennifer v1.7.1 // indirect - github.com/dogmatiq/jumble v0.1.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect diff --git a/go.sum b/go.sum index c988bb6e..ea224023 100644 --- a/go.sum +++ b/go.sum @@ -16,10 +16,10 @@ github.com/dogmatiq/dogma v0.25.0 h1:L1NM8xBaQMyJ+oFSKSH9FWqyQyf91I50qFN/Bz4WsT0 github.com/dogmatiq/dogma v0.25.0/go.mod h1:BNKrZq9wm3jRu35XUWQXkMRhq4EzYK+rOVbGjrbCVyI= github.com/dogmatiq/jumble v0.1.0 h1:Cb3ExfxY+AoUP4G9/sOwoOdYX8o+kOLK8+dhXAry+QA= github.com/dogmatiq/jumble v0.1.0/go.mod h1:FCGV2ImXu8zvThxhd4QLstiEdu74vbIVw9bFJSBcKr4= -github.com/dogmatiq/primo v0.4.3 h1:Q6+HzBYuhLhrrwKWkgHb3MOo5JLHTneN+lgmtgGDavI= -github.com/dogmatiq/primo v0.4.3/go.mod h1:Bb1BMVwxC+adAs/Io6tACagI0OvTCGHKNQQ62YtrW1w= github.com/dogmatiq/primo v0.4.4 h1:jM5WWBsEENz/ss3S5B3Dq5c+OkR6wYjjRQgaYofzJfs= github.com/dogmatiq/primo v0.4.4/go.mod h1:Bb1BMVwxC+adAs/Io6tACagI0OvTCGHKNQQ62YtrW1w= +github.com/dogmatiq/protobuf v0.2.0 h1:HMbG3Ur30fglm1Q+4EenIxNxAuiyJhqMWaLmtdxyO/k= +github.com/dogmatiq/protobuf v0.2.0/go.mod h1:wRsDs0xjHx0Hhfvh7n4xzSngeAl3YGZFOgtxyalDzQE= github.com/dogmatiq/spruce v0.2.4 h1:32HqvqvlINlvMKzQ4eWO97+MdI+1CfLfr9RmsTvDphk= github.com/dogmatiq/spruce v0.2.4/go.mod h1:za5ZdNvh+FRWg4B3DCn8jfNB2LVR/9Dk3fkuHVDJLrk= github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= diff --git a/grpc/messaginggrpc/commandexecutor.pb.go b/grpc/messaginggrpc/commandexecutor.pb.go deleted file mode 100644 index 9b2e3506..00000000 --- a/grpc/messaginggrpc/commandexecutor.pb.go +++ /dev/null @@ -1,543 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.12 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/commandexecutor.proto - -package messaginggrpc - -import ( - envelopepb "github.com/dogmatiq/enginekit/protobuf/envelopepb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// ExecuteCommandRequest is the input to the [CommandExecutorAPI.ExecuteCommand] -// method. -type ExecuteCommandRequest struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_ApplicationKey *uuidpb.UUID `protobuf:"bytes,1,opt,name=application_key,json=applicationKey"` - xxx_hidden_MessageTypeId *uuidpb.UUID `protobuf:"bytes,2,opt,name=message_type_id,json=messageTypeId"` - xxx_hidden_Data []byte `protobuf:"bytes,3,opt,name=data"` - xxx_hidden_IdempotencyKey string `protobuf:"bytes,4,opt,name=idempotency_key,json=idempotencyKey"` - xxx_hidden_ObservedMessageTypeIds *[]*uuidpb.UUID `protobuf:"bytes,5,rep,name=observed_message_type_ids,json=observedMessageTypeIds"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ExecuteCommandRequest) Reset() { - *x = ExecuteCommandRequest{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ExecuteCommandRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecuteCommandRequest) ProtoMessage() {} - -func (x *ExecuteCommandRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *ExecuteCommandRequest) GetApplicationKey() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_ApplicationKey - } - return nil -} - -func (x *ExecuteCommandRequest) GetMessageTypeId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_MessageTypeId - } - return nil -} - -func (x *ExecuteCommandRequest) GetData() []byte { - if x != nil { - return x.xxx_hidden_Data - } - return nil -} - -func (x *ExecuteCommandRequest) GetIdempotencyKey() string { - if x != nil { - return x.xxx_hidden_IdempotencyKey - } - return "" -} - -func (x *ExecuteCommandRequest) GetObservedMessageTypeIds() []*uuidpb.UUID { - if x != nil { - if x.xxx_hidden_ObservedMessageTypeIds != nil { - return *x.xxx_hidden_ObservedMessageTypeIds - } - } - return nil -} - -func (x *ExecuteCommandRequest) SetApplicationKey(v *uuidpb.UUID) { - x.xxx_hidden_ApplicationKey = v -} - -func (x *ExecuteCommandRequest) SetMessageTypeId(v *uuidpb.UUID) { - x.xxx_hidden_MessageTypeId = v -} - -func (x *ExecuteCommandRequest) SetData(v []byte) { - if v == nil { - v = []byte{} - } - x.xxx_hidden_Data = v -} - -func (x *ExecuteCommandRequest) SetIdempotencyKey(v string) { - x.xxx_hidden_IdempotencyKey = v -} - -func (x *ExecuteCommandRequest) SetObservedMessageTypeIds(v []*uuidpb.UUID) { - x.xxx_hidden_ObservedMessageTypeIds = &v -} - -func (x *ExecuteCommandRequest) HasApplicationKey() bool { - if x == nil { - return false - } - return x.xxx_hidden_ApplicationKey != nil -} - -func (x *ExecuteCommandRequest) HasMessageTypeId() bool { - if x == nil { - return false - } - return x.xxx_hidden_MessageTypeId != nil -} - -func (x *ExecuteCommandRequest) ClearApplicationKey() { - x.xxx_hidden_ApplicationKey = nil -} - -func (x *ExecuteCommandRequest) ClearMessageTypeId() { - x.xxx_hidden_MessageTypeId = nil -} - -type ExecuteCommandRequest_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // ApplicationKey is the key of the application that is the target of the - // command. - ApplicationKey *uuidpb.UUID - // MessageTypeId is a unique identifier for the command's message type, as - // per the Dogma message type registry. - MessageTypeId *uuidpb.UUID - // Data is the binary command data obtained by calling - // [dogma.Message.MarshalBinary] on the command. - Data []byte - // IdempotencyKey is an (optional) application-defined value used to - // identify the command across retries. - // - // If it is non-empty, the server MUST NOT execute the command again if it - // has already been executed with the same idempotency key. - IdempotencyKey string - // ObservedMessageTypeIds is a list of message type IDs identifying the events - // to be observed as a result of executing the command. The client must be - // explicit about the event types that it understands; there is no mechanism - // to observe all event types. - ObservedMessageTypeIds []*uuidpb.UUID -} - -func (b0 ExecuteCommandRequest_builder) Build() *ExecuteCommandRequest { - m0 := &ExecuteCommandRequest{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_ApplicationKey = b.ApplicationKey - x.xxx_hidden_MessageTypeId = b.MessageTypeId - x.xxx_hidden_Data = b.Data - x.xxx_hidden_IdempotencyKey = b.IdempotencyKey - x.xxx_hidden_ObservedMessageTypeIds = &b.ObservedMessageTypeIds - return m0 -} - -// ExecuteCommandResponse is the streaming output of the -// [CommandExecutorAPI.ExecuteCommand] method. -type ExecuteCommandResponse struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Operation isExecuteCommandResponse_Operation `protobuf_oneof:"operation"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ExecuteCommandResponse) Reset() { - *x = ExecuteCommandResponse{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ExecuteCommandResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecuteCommandResponse) ProtoMessage() {} - -func (x *ExecuteCommandResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *ExecuteCommandResponse) GetCommandAccepted() *ExecuteCommandResponse_CommandAccepted { - if x != nil { - if x, ok := x.xxx_hidden_Operation.(*executeCommandResponse_CommandAccepted_); ok { - return x.CommandAccepted - } - } - return nil -} - -func (x *ExecuteCommandResponse) GetEventRecorded() *ExecuteCommandResponse_EventRecorded { - if x != nil { - if x, ok := x.xxx_hidden_Operation.(*executeCommandResponse_EventRecorded_); ok { - return x.EventRecorded - } - } - return nil -} - -func (x *ExecuteCommandResponse) SetCommandAccepted(v *ExecuteCommandResponse_CommandAccepted) { - if v == nil { - x.xxx_hidden_Operation = nil - return - } - x.xxx_hidden_Operation = &executeCommandResponse_CommandAccepted_{v} -} - -func (x *ExecuteCommandResponse) SetEventRecorded(v *ExecuteCommandResponse_EventRecorded) { - if v == nil { - x.xxx_hidden_Operation = nil - return - } - x.xxx_hidden_Operation = &executeCommandResponse_EventRecorded_{v} -} - -func (x *ExecuteCommandResponse) HasOperation() bool { - if x == nil { - return false - } - return x.xxx_hidden_Operation != nil -} - -func (x *ExecuteCommandResponse) HasCommandAccepted() bool { - if x == nil { - return false - } - _, ok := x.xxx_hidden_Operation.(*executeCommandResponse_CommandAccepted_) - return ok -} - -func (x *ExecuteCommandResponse) HasEventRecorded() bool { - if x == nil { - return false - } - _, ok := x.xxx_hidden_Operation.(*executeCommandResponse_EventRecorded_) - return ok -} - -func (x *ExecuteCommandResponse) ClearOperation() { - x.xxx_hidden_Operation = nil -} - -func (x *ExecuteCommandResponse) ClearCommandAccepted() { - if _, ok := x.xxx_hidden_Operation.(*executeCommandResponse_CommandAccepted_); ok { - x.xxx_hidden_Operation = nil - } -} - -func (x *ExecuteCommandResponse) ClearEventRecorded() { - if _, ok := x.xxx_hidden_Operation.(*executeCommandResponse_EventRecorded_); ok { - x.xxx_hidden_Operation = nil - } -} - -const ExecuteCommandResponse_Operation_not_set_case case_ExecuteCommandResponse_Operation = 0 -const ExecuteCommandResponse_CommandAccepted_case case_ExecuteCommandResponse_Operation = 1 -const ExecuteCommandResponse_EventRecorded_case case_ExecuteCommandResponse_Operation = 2 - -func (x *ExecuteCommandResponse) WhichOperation() case_ExecuteCommandResponse_Operation { - if x == nil { - return ExecuteCommandResponse_Operation_not_set_case - } - switch x.xxx_hidden_Operation.(type) { - case *executeCommandResponse_CommandAccepted_: - return ExecuteCommandResponse_CommandAccepted_case - case *executeCommandResponse_EventRecorded_: - return ExecuteCommandResponse_EventRecorded_case - default: - return ExecuteCommandResponse_Operation_not_set_case - } -} - -type ExecuteCommandResponse_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // Fields of oneof xxx_hidden_Operation: - CommandAccepted *ExecuteCommandResponse_CommandAccepted - EventRecorded *ExecuteCommandResponse_EventRecorded - // -- end of xxx_hidden_Operation -} - -func (b0 ExecuteCommandResponse_builder) Build() *ExecuteCommandResponse { - m0 := &ExecuteCommandResponse{} - b, x := &b0, m0 - _, _ = b, x - if b.CommandAccepted != nil { - x.xxx_hidden_Operation = &executeCommandResponse_CommandAccepted_{b.CommandAccepted} - } - if b.EventRecorded != nil { - x.xxx_hidden_Operation = &executeCommandResponse_EventRecorded_{b.EventRecorded} - } - return m0 -} - -type case_ExecuteCommandResponse_Operation protoreflect.FieldNumber - -func (x case_ExecuteCommandResponse_Operation) String() string { - md := file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[1].Descriptor() - if x == 0 { - return "not set" - } - return protoimpl.X.MessageFieldStringOf(md, protoreflect.FieldNumber(x)) -} - -type isExecuteCommandResponse_Operation interface { - isExecuteCommandResponse_Operation() -} - -type executeCommandResponse_CommandAccepted_ struct { - CommandAccepted *ExecuteCommandResponse_CommandAccepted `protobuf:"bytes,1,opt,name=command_accepted,json=commandAccepted,oneof"` -} - -type executeCommandResponse_EventRecorded_ struct { - EventRecorded *ExecuteCommandResponse_EventRecorded `protobuf:"bytes,2,opt,name=event_recorded,json=eventRecorded,oneof"` -} - -func (*executeCommandResponse_CommandAccepted_) isExecuteCommandResponse_Operation() {} - -func (*executeCommandResponse_EventRecorded_) isExecuteCommandResponse_Operation() {} - -// CommandAccepted indicates that the engine has taken ownership of the -// command. -type ExecuteCommandResponse_CommandAccepted struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ExecuteCommandResponse_CommandAccepted) Reset() { - *x = ExecuteCommandResponse_CommandAccepted{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ExecuteCommandResponse_CommandAccepted) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecuteCommandResponse_CommandAccepted) ProtoMessage() {} - -func (x *ExecuteCommandResponse_CommandAccepted) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -type ExecuteCommandResponse_CommandAccepted_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - -} - -func (b0 ExecuteCommandResponse_CommandAccepted_builder) Build() *ExecuteCommandResponse_CommandAccepted { - m0 := &ExecuteCommandResponse_CommandAccepted{} - b, x := &b0, m0 - _, _ = b, x - return m0 -} - -// EventRecorded represents the delivery of a single event that was recorded -// as a result of executing the command. -type ExecuteCommandResponse_EventRecorded struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Envelope *envelopepb.Envelope `protobuf:"bytes,1,opt,name=envelope"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ExecuteCommandResponse_EventRecorded) Reset() { - *x = ExecuteCommandResponse_EventRecorded{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ExecuteCommandResponse_EventRecorded) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecuteCommandResponse_EventRecorded) ProtoMessage() {} - -func (x *ExecuteCommandResponse_EventRecorded) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *ExecuteCommandResponse_EventRecorded) GetEnvelope() *envelopepb.Envelope { - if x != nil { - return x.xxx_hidden_Envelope - } - return nil -} - -func (x *ExecuteCommandResponse_EventRecorded) SetEnvelope(v *envelopepb.Envelope) { - x.xxx_hidden_Envelope = v -} - -func (x *ExecuteCommandResponse_EventRecorded) HasEnvelope() bool { - if x == nil { - return false - } - return x.xxx_hidden_Envelope != nil -} - -func (x *ExecuteCommandResponse_EventRecorded) ClearEnvelope() { - x.xxx_hidden_Envelope = nil -} - -type ExecuteCommandResponse_EventRecorded_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // Envelope is the envelope containing the event. - Envelope *envelopepb.Envelope -} - -func (b0 ExecuteCommandResponse_EventRecorded_builder) Build() *ExecuteCommandResponse_EventRecorded { - m0 := &ExecuteCommandResponse_EventRecorded{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_Envelope = b.Envelope - return m0 -} - -var File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_rawDesc = "" + - "\n" + - "Fgithub.com/dogmatiq/enginekit/grpc/messaginggrpc/commandexecutor.proto\x12\x12dogma.messaging.v1\x1a@github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto\x1a8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\"\xb0\x02\n" + - "\x15ExecuteCommandRequest\x12=\n" + - "\x0fapplication_key\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\x0eapplicationKey\x12<\n" + - "\x0fmessage_type_id\x18\x02 \x01(\v2\x14.dogma.protobuf.UUIDR\rmessageTypeId\x12\x19\n" + - "\x04data\x18\x03 \x01(\fB\x05\xaa\x01\x02\b\x02R\x04data\x12.\n" + - "\x0fidempotency_key\x18\x04 \x01(\tB\x05\xaa\x01\x02\b\x02R\x0eidempotencyKey\x12O\n" + - "\x19observed_message_type_ids\x18\x05 \x03(\v2\x14.dogma.protobuf.UUIDR\x16observedMessageTypeIds\"\xcb\x02\n" + - "\x16ExecuteCommandResponse\x12g\n" + - "\x10command_accepted\x18\x01 \x01(\v2:.dogma.messaging.v1.ExecuteCommandResponse.CommandAcceptedH\x00R\x0fcommandAccepted\x12a\n" + - "\x0eevent_recorded\x18\x02 \x01(\v28.dogma.messaging.v1.ExecuteCommandResponse.EventRecordedH\x00R\reventRecorded\x1a\x11\n" + - "\x0fCommandAccepted\x1aE\n" + - "\rEventRecorded\x124\n" + - "\benvelope\x18\x01 \x01(\v2\x18.dogma.protobuf.EnvelopeR\benvelopeB\v\n" + - "\toperation2\x7f\n" + - "\x12CommandExecutorAPI\x12i\n" + - "\x0eExecuteCommand\x12).dogma.messaging.v1.ExecuteCommandRequest\x1a*.dogma.messaging.v1.ExecuteCommandResponse0\x01B2Z0github.com/dogmatiq/enginekit/grpc/messaginggrpcb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_goTypes = []any{ - (*ExecuteCommandRequest)(nil), // 0: dogma.messaging.v1.ExecuteCommandRequest - (*ExecuteCommandResponse)(nil), // 1: dogma.messaging.v1.ExecuteCommandResponse - (*ExecuteCommandResponse_CommandAccepted)(nil), // 2: dogma.messaging.v1.ExecuteCommandResponse.CommandAccepted - (*ExecuteCommandResponse_EventRecorded)(nil), // 3: dogma.messaging.v1.ExecuteCommandResponse.EventRecorded - (*uuidpb.UUID)(nil), // 4: dogma.protobuf.UUID - (*envelopepb.Envelope)(nil), // 5: dogma.protobuf.Envelope -} -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_depIdxs = []int32{ - 4, // 0: dogma.messaging.v1.ExecuteCommandRequest.application_key:type_name -> dogma.protobuf.UUID - 4, // 1: dogma.messaging.v1.ExecuteCommandRequest.message_type_id:type_name -> dogma.protobuf.UUID - 4, // 2: dogma.messaging.v1.ExecuteCommandRequest.observed_message_type_ids:type_name -> dogma.protobuf.UUID - 2, // 3: dogma.messaging.v1.ExecuteCommandResponse.command_accepted:type_name -> dogma.messaging.v1.ExecuteCommandResponse.CommandAccepted - 3, // 4: dogma.messaging.v1.ExecuteCommandResponse.event_recorded:type_name -> dogma.messaging.v1.ExecuteCommandResponse.EventRecorded - 5, // 5: dogma.messaging.v1.ExecuteCommandResponse.EventRecorded.envelope:type_name -> dogma.protobuf.Envelope - 0, // 6: dogma.messaging.v1.CommandExecutorAPI.ExecuteCommand:input_type -> dogma.messaging.v1.ExecuteCommandRequest - 1, // 7: dogma.messaging.v1.CommandExecutorAPI.ExecuteCommand:output_type -> dogma.messaging.v1.ExecuteCommandResponse - 7, // [7:8] is the sub-list for method output_type - 6, // [6:7] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_init() } -func file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_init() { - if File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto != nil { - return - } - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes[1].OneofWrappers = []any{ - (*executeCommandResponse_CommandAccepted_)(nil), - (*executeCommandResponse_EventRecorded_)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_rawDesc)), - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto = out.File - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_commandexecutor_proto_depIdxs = nil -} diff --git a/grpc/messaginggrpc/commandexecutor.proto b/grpc/messaginggrpc/commandexecutor.proto deleted file mode 100644 index 86e39401..00000000 --- a/grpc/messaginggrpc/commandexecutor.proto +++ /dev/null @@ -1,110 +0,0 @@ -edition = "2024"; -package dogma.messaging.v1; - -option go_package = "github.com/dogmatiq/enginekit/grpc/messaginggrpc"; - -import "github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto"; -import "github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto"; - -// CommandExecutorAPI is a service for executing commands within a Dogma -// application hosted by the engine on the server. -service CommandExecutorAPI { - // ExecuteCommand submits a command for execution, and optionally observes - // the events that are recorded as a result of executing it. - // - // If the requested application key is unknown to the server it MUST return - // a NOT_FOUND error with an attached [UnrecognizedApplication] value. See - // [UnrecognizedApplicationError]. - // - // If the requested command type ID does not identify a command that is - // executable within the target application the server MUST return an - // INVALID_ARGUMENT error with an attached [UnrecognizedCommandType] value. - // See [UnrecognizedCommandTypeError]. - // - // If the command data cannot be unmarshaled the server MUST return an - // INVALID_ARGUMENT error with an attached [MalformedMessage] value. See - // [MalformedMessageError]. - // - // If the command is well-formed but fails the application's validation - // logic the server MUST return an INVALID_ARGUMENT error with an attached - // [InvalidMessage] value. See [InvalidMessageError]. - // - // The requested event type IDs MUST identify event types that may be - // recorded by the target application. If any other type IDs are requested - // the server MUST return an INVALID_ARGUMENT error with an attached - // [UnrecognizedEventType] value for each unrecognized type ID. See - // [UnrecognizedEventTypeError]. - // - // The first response MUST be a [CommandAccepted] operation, sent once the - // engine has taken ownership of the command. Ownership means that the - // command has been durably accepted for execution; it does not mean that - // handling of the command is complete. - // - // Subsequent responses each deliver a single event that was recorded as a - // result of executing the command and that matches one of the requested - // event type IDs. If no event type IDs are requested the server MUST end - // the stream immediately after sending the [CommandAccepted] operation. - // - // The server MUST end the stream with an OK status once it determines that - // no further relevant events can occur. Any other outcome, such as a - // network failure or server shutdown, leaves the client unable to resume - // observation; the client may re-execute the command using the same - // idempotency key to confirm its acceptance. - // - // If the command is a duplicate, as identified by its idempotency key, the - // server MUST NOT execute it again, but MUST still send a [CommandAccepted] - // operation. The server SHOULD deliver the relevant events recorded by the - // original execution, but MAY end the stream immediately if it is unable to - // determine which events those are. - rpc ExecuteCommand(ExecuteCommandRequest) - returns (stream ExecuteCommandResponse); -} - -// ExecuteCommandRequest is the input to the [CommandExecutorAPI.ExecuteCommand] -// method. -message ExecuteCommandRequest { - // ApplicationKey is the key of the application that is the target of the - // command. - dogma.protobuf.UUID application_key = 1; - - // MessageTypeId is a unique identifier for the command's message type, as - // per the Dogma message type registry. - dogma.protobuf.UUID message_type_id = 2; - - // Data is the binary command data obtained by calling - // [dogma.Message.MarshalBinary] on the command. - bytes data = 3 [features.field_presence = IMPLICIT]; - - // IdempotencyKey is an (optional) application-defined value used to - // identify the command across retries. - // - // If it is non-empty, the server MUST NOT execute the command again if it - // has already been executed with the same idempotency key. - string idempotency_key = 4 [features.field_presence = IMPLICIT]; - - // ObservedMessageTypeIds is a list of message type IDs identifying the events - // to be observed as a result of executing the command. The client must be - // explicit about the event types that it understands; there is no mechanism - // to observe all event types. - repeated dogma.protobuf.UUID observed_message_type_ids = 5; -} - -// ExecuteCommandResponse is the streaming output of the -// [CommandExecutorAPI.ExecuteCommand] method. -message ExecuteCommandResponse { - // CommandAccepted indicates that the engine has taken ownership of the - // command. - message CommandAccepted {} - - // EventRecorded represents the delivery of a single event that was recorded - // as a result of executing the command. - message EventRecorded { - // Envelope is the envelope containing the event. - dogma.protobuf.Envelope envelope = 1; - } - - oneof operation { - CommandAccepted command_accepted = 1; - EventRecorded event_recorded = 2; - } -} diff --git a/grpc/messaginggrpc/commandexecutor_grpc.pb.go b/grpc/messaginggrpc/commandexecutor_grpc.pb.go deleted file mode 100644 index a7cd8ece..00000000 --- a/grpc/messaginggrpc/commandexecutor_grpc.pb.go +++ /dev/null @@ -1,222 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.6.2 -// - protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/commandexecutor.proto - -package messaginggrpc - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - CommandExecutorAPI_ExecuteCommand_FullMethodName = "/dogma.messaging.v1.CommandExecutorAPI/ExecuteCommand" -) - -// CommandExecutorAPIClient is the client API for CommandExecutorAPI service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// CommandExecutorAPI is a service for executing commands within a Dogma -// application hosted by the engine on the server. -type CommandExecutorAPIClient interface { - // ExecuteCommand submits a command for execution, and optionally observes - // the events that are recorded as a result of executing it. - // - // If the requested application key is unknown to the server it MUST return - // a NOT_FOUND error with an attached [UnrecognizedApplication] value. See - // [UnrecognizedApplicationError]. - // - // If the requested command type ID does not identify a command that is - // executable within the target application the server MUST return an - // INVALID_ARGUMENT error with an attached [UnrecognizedCommandType] value. - // See [UnrecognizedCommandTypeError]. - // - // If the command data cannot be unmarshaled the server MUST return an - // INVALID_ARGUMENT error with an attached [MalformedMessage] value. See - // [MalformedMessageError]. - // - // If the command is well-formed but fails the application's validation - // logic the server MUST return an INVALID_ARGUMENT error with an attached - // [InvalidMessage] value. See [InvalidMessageError]. - // - // The requested event type IDs MUST identify event types that may be - // recorded by the target application. If any other type IDs are requested - // the server MUST return an INVALID_ARGUMENT error with an attached - // [UnrecognizedEventType] value for each unrecognized type ID. See - // [UnrecognizedEventTypeError]. - // - // The first response MUST be a [CommandAccepted] operation, sent once the - // engine has taken ownership of the command. Ownership means that the - // command has been durably accepted for execution; it does not mean that - // handling of the command is complete. - // - // Subsequent responses each deliver a single event that was recorded as a - // result of executing the command and that matches one of the requested - // event type IDs. If no event type IDs are requested the server MUST end - // the stream immediately after sending the [CommandAccepted] operation. - // - // The server MUST end the stream with an OK status once it determines that - // no further relevant events can occur. Any other outcome, such as a - // network failure or server shutdown, leaves the client unable to resume - // observation; the client may re-execute the command using the same - // idempotency key to confirm its acceptance. - // - // If the command is a duplicate, as identified by its idempotency key, the - // server MUST NOT execute it again, but MUST still send a [CommandAccepted] - // operation. The server SHOULD deliver the relevant events recorded by the - // original execution, but MAY end the stream immediately if it is unable to - // determine which events those are. - ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ExecuteCommandResponse], error) -} - -type commandExecutorAPIClient struct { - cc grpc.ClientConnInterface -} - -func NewCommandExecutorAPIClient(cc grpc.ClientConnInterface) CommandExecutorAPIClient { - return &commandExecutorAPIClient{cc} -} - -func (c *commandExecutorAPIClient) ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ExecuteCommandResponse], error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &CommandExecutorAPI_ServiceDesc.Streams[0], CommandExecutorAPI_ExecuteCommand_FullMethodName, cOpts...) - if err != nil { - return nil, err - } - x := &grpc.GenericClientStream[ExecuteCommandRequest, ExecuteCommandResponse]{ClientStream: stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type CommandExecutorAPI_ExecuteCommandClient = grpc.ServerStreamingClient[ExecuteCommandResponse] - -// CommandExecutorAPIServer is the server API for CommandExecutorAPI service. -// All implementations should embed UnimplementedCommandExecutorAPIServer -// for forward compatibility. -// -// CommandExecutorAPI is a service for executing commands within a Dogma -// application hosted by the engine on the server. -type CommandExecutorAPIServer interface { - // ExecuteCommand submits a command for execution, and optionally observes - // the events that are recorded as a result of executing it. - // - // If the requested application key is unknown to the server it MUST return - // a NOT_FOUND error with an attached [UnrecognizedApplication] value. See - // [UnrecognizedApplicationError]. - // - // If the requested command type ID does not identify a command that is - // executable within the target application the server MUST return an - // INVALID_ARGUMENT error with an attached [UnrecognizedCommandType] value. - // See [UnrecognizedCommandTypeError]. - // - // If the command data cannot be unmarshaled the server MUST return an - // INVALID_ARGUMENT error with an attached [MalformedMessage] value. See - // [MalformedMessageError]. - // - // If the command is well-formed but fails the application's validation - // logic the server MUST return an INVALID_ARGUMENT error with an attached - // [InvalidMessage] value. See [InvalidMessageError]. - // - // The requested event type IDs MUST identify event types that may be - // recorded by the target application. If any other type IDs are requested - // the server MUST return an INVALID_ARGUMENT error with an attached - // [UnrecognizedEventType] value for each unrecognized type ID. See - // [UnrecognizedEventTypeError]. - // - // The first response MUST be a [CommandAccepted] operation, sent once the - // engine has taken ownership of the command. Ownership means that the - // command has been durably accepted for execution; it does not mean that - // handling of the command is complete. - // - // Subsequent responses each deliver a single event that was recorded as a - // result of executing the command and that matches one of the requested - // event type IDs. If no event type IDs are requested the server MUST end - // the stream immediately after sending the [CommandAccepted] operation. - // - // The server MUST end the stream with an OK status once it determines that - // no further relevant events can occur. Any other outcome, such as a - // network failure or server shutdown, leaves the client unable to resume - // observation; the client may re-execute the command using the same - // idempotency key to confirm its acceptance. - // - // If the command is a duplicate, as identified by its idempotency key, the - // server MUST NOT execute it again, but MUST still send a [CommandAccepted] - // operation. The server SHOULD deliver the relevant events recorded by the - // original execution, but MAY end the stream immediately if it is unable to - // determine which events those are. - ExecuteCommand(*ExecuteCommandRequest, grpc.ServerStreamingServer[ExecuteCommandResponse]) error -} - -// UnimplementedCommandExecutorAPIServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedCommandExecutorAPIServer struct{} - -func (UnimplementedCommandExecutorAPIServer) ExecuteCommand(*ExecuteCommandRequest, grpc.ServerStreamingServer[ExecuteCommandResponse]) error { - return status.Error(codes.Unimplemented, "method ExecuteCommand not implemented") -} -func (UnimplementedCommandExecutorAPIServer) testEmbeddedByValue() {} - -// UnsafeCommandExecutorAPIServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to CommandExecutorAPIServer will -// result in compilation errors. -type UnsafeCommandExecutorAPIServer interface { - mustEmbedUnimplementedCommandExecutorAPIServer() -} - -func RegisterCommandExecutorAPIServer(s grpc.ServiceRegistrar, srv CommandExecutorAPIServer) { - // If the following call panics, it indicates UnimplementedCommandExecutorAPIServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&CommandExecutorAPI_ServiceDesc, srv) -} - -func _CommandExecutorAPI_ExecuteCommand_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ExecuteCommandRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(CommandExecutorAPIServer).ExecuteCommand(m, &grpc.GenericServerStream[ExecuteCommandRequest, ExecuteCommandResponse]{ServerStream: stream}) -} - -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type CommandExecutorAPI_ExecuteCommandServer = grpc.ServerStreamingServer[ExecuteCommandResponse] - -// CommandExecutorAPI_ServiceDesc is the grpc.ServiceDesc for CommandExecutorAPI service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var CommandExecutorAPI_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "dogma.messaging.v1.CommandExecutorAPI", - HandlerType: (*CommandExecutorAPIServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "ExecuteCommand", - Handler: _CommandExecutorAPI_ExecuteCommand_Handler, - ServerStreams: true, - }, - }, - Metadata: "github.com/dogmatiq/enginekit/grpc/messaginggrpc/commandexecutor.proto", -} diff --git a/grpc/messaginggrpc/commandexecutor_primo.pb.go b/grpc/messaginggrpc/commandexecutor_primo.pb.go deleted file mode 100644 index e1b6a137..00000000 --- a/grpc/messaginggrpc/commandexecutor_primo.pb.go +++ /dev/null @@ -1,692 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/commandexecutor.proto - -package messaginggrpc - -import ( - "context" - "fmt" - envelopepb "github.com/dogmatiq/enginekit/protobuf/envelopepb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - proto "google.golang.org/protobuf/proto" -) - -// TryGetCommandAccepted returns the CommandAccepted value if x.Operation is set to CommandAccepted. -// Otherwise, ok is false and v is the zero-value. -func (x *ExecuteCommandResponse) TryGetCommandAccepted() (v *ExecuteCommandResponse_CommandAccepted, ok bool) { - if x.HasCommandAccepted() { - return x.GetCommandAccepted(), true - } - return v, false -} - -// TryGetEventRecorded returns the EventRecorded value if x.Operation is set to EventRecorded. -// Otherwise, ok is false and v is the zero-value. -func (x *ExecuteCommandResponse) TryGetEventRecorded() (v *ExecuteCommandResponse_EventRecorded, ok bool) { - if x.HasEventRecorded() { - return x.GetEventRecorded(), true - } - return v, false -} - -type ExecuteCommandRequestBuilder struct { - prototype ExecuteCommandRequest -} - -// NewExecuteCommandRequestBuilder returns a builder that constructs [ExecuteCommandRequest] messages. -func NewExecuteCommandRequestBuilder() *ExecuteCommandRequestBuilder { - return &ExecuteCommandRequestBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ExecuteCommandRequestBuilder) From(x *ExecuteCommandRequest) *ExecuteCommandRequestBuilder { - proto.Reset(&b.prototype) - if x.HasApplicationKey() { - b.prototype.SetApplicationKey(x.GetApplicationKey()) - } - if x.HasMessageTypeId() { - b.prototype.SetMessageTypeId(x.GetMessageTypeId()) - } - b.prototype.SetData(x.GetData()) - b.prototype.SetIdempotencyKey(x.GetIdempotencyKey()) - b.prototype.SetObservedMessageTypeIds(x.GetObservedMessageTypeIds()) - return b -} - -// Build returns a new [ExecuteCommandRequest] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ExecuteCommandRequestBuilder) Build() *ExecuteCommandRequest { - m := &ExecuteCommandRequest{} - if b.prototype.HasApplicationKey() { - m.SetApplicationKey(b.prototype.GetApplicationKey()) - } - if b.prototype.HasMessageTypeId() { - m.SetMessageTypeId(b.prototype.GetMessageTypeId()) - } - m.SetData(b.prototype.GetData()) - m.SetIdempotencyKey(b.prototype.GetIdempotencyKey()) - m.SetObservedMessageTypeIds(b.prototype.GetObservedMessageTypeIds()) - return m -} - -// WithApplicationKey configures the builder to set the ApplicationKey field to v, -// then returns b. -func (b *ExecuteCommandRequestBuilder) WithApplicationKey(v *uuidpb.UUID) *ExecuteCommandRequestBuilder { - b.prototype.SetApplicationKey(v) - return b -} - -// WithMessageTypeId configures the builder to set the MessageTypeId field to v, -// then returns b. -func (b *ExecuteCommandRequestBuilder) WithMessageTypeId(v *uuidpb.UUID) *ExecuteCommandRequestBuilder { - b.prototype.SetMessageTypeId(v) - return b -} - -// WithData configures the builder to set the Data field to v, -// then returns b. -func (b *ExecuteCommandRequestBuilder) WithData(v []byte) *ExecuteCommandRequestBuilder { - b.prototype.SetData(v) - return b -} - -// WithIdempotencyKey configures the builder to set the IdempotencyKey field to v, -// then returns b. -func (b *ExecuteCommandRequestBuilder) WithIdempotencyKey(v string) *ExecuteCommandRequestBuilder { - b.prototype.SetIdempotencyKey(v) - return b -} - -// WithObservedMessageTypeIds configures the builder to set the ObservedMessageTypeIds field to v, -// then returns b. -func (b *ExecuteCommandRequestBuilder) WithObservedMessageTypeIds(v []*uuidpb.UUID) *ExecuteCommandRequestBuilder { - b.prototype.SetObservedMessageTypeIds(v) - return b -} - -type ExecuteCommandResponseBuilder struct { - prototype ExecuteCommandResponse -} - -// NewExecuteCommandResponseBuilder returns a builder that constructs [ExecuteCommandResponse] messages. -func NewExecuteCommandResponseBuilder() *ExecuteCommandResponseBuilder { - return &ExecuteCommandResponseBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ExecuteCommandResponseBuilder) From(x *ExecuteCommandResponse) *ExecuteCommandResponseBuilder { - proto.Reset(&b.prototype) - if x.HasCommandAccepted() { - b.prototype.SetCommandAccepted(x.GetCommandAccepted()) - } - if x.HasEventRecorded() { - b.prototype.SetEventRecorded(x.GetEventRecorded()) - } - return b -} - -// Build returns a new [ExecuteCommandResponse] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ExecuteCommandResponseBuilder) Build() *ExecuteCommandResponse { - m := &ExecuteCommandResponse{} - if b.prototype.HasCommandAccepted() { - m.SetCommandAccepted(b.prototype.GetCommandAccepted()) - } - if b.prototype.HasEventRecorded() { - m.SetEventRecorded(b.prototype.GetEventRecorded()) - } - return m -} - -// WithCommandAccepted configures the builder to set the CommandAccepted field to v, -// then returns b. -func (b *ExecuteCommandResponseBuilder) WithCommandAccepted(v *ExecuteCommandResponse_CommandAccepted) *ExecuteCommandResponseBuilder { - b.prototype.SetCommandAccepted(v) - return b -} - -// WithEventRecorded configures the builder to set the EventRecorded field to v, -// then returns b. -func (b *ExecuteCommandResponseBuilder) WithEventRecorded(v *ExecuteCommandResponse_EventRecorded) *ExecuteCommandResponseBuilder { - b.prototype.SetEventRecorded(v) - return b -} - -type ExecuteCommandResponse_CommandAcceptedBuilder struct { - prototype ExecuteCommandResponse_CommandAccepted -} - -// NewExecuteCommandResponse_CommandAcceptedBuilder returns a builder that constructs [ExecuteCommandResponse_CommandAccepted] messages. -func NewExecuteCommandResponse_CommandAcceptedBuilder() *ExecuteCommandResponse_CommandAcceptedBuilder { - return &ExecuteCommandResponse_CommandAcceptedBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ExecuteCommandResponse_CommandAcceptedBuilder) From(x *ExecuteCommandResponse_CommandAccepted) *ExecuteCommandResponse_CommandAcceptedBuilder { - proto.Reset(&b.prototype) - return b -} - -// Build returns a new [ExecuteCommandResponse_CommandAccepted] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ExecuteCommandResponse_CommandAcceptedBuilder) Build() *ExecuteCommandResponse_CommandAccepted { - m := &ExecuteCommandResponse_CommandAccepted{} - return m -} - -type ExecuteCommandResponse_EventRecordedBuilder struct { - prototype ExecuteCommandResponse_EventRecorded -} - -// NewExecuteCommandResponse_EventRecordedBuilder returns a builder that constructs [ExecuteCommandResponse_EventRecorded] messages. -func NewExecuteCommandResponse_EventRecordedBuilder() *ExecuteCommandResponse_EventRecordedBuilder { - return &ExecuteCommandResponse_EventRecordedBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ExecuteCommandResponse_EventRecordedBuilder) From(x *ExecuteCommandResponse_EventRecorded) *ExecuteCommandResponse_EventRecordedBuilder { - proto.Reset(&b.prototype) - if x.HasEnvelope() { - b.prototype.SetEnvelope(x.GetEnvelope()) - } - return b -} - -// Build returns a new [ExecuteCommandResponse_EventRecorded] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ExecuteCommandResponse_EventRecordedBuilder) Build() *ExecuteCommandResponse_EventRecorded { - m := &ExecuteCommandResponse_EventRecorded{} - if b.prototype.HasEnvelope() { - m.SetEnvelope(b.prototype.GetEnvelope()) - } - return m -} - -// WithEnvelope configures the builder to set the Envelope field to v, -// then returns b. -func (b *ExecuteCommandResponse_EventRecordedBuilder) WithEnvelope(v *envelopepb.Envelope) *ExecuteCommandResponse_EventRecordedBuilder { - b.prototype.SetEnvelope(v) - return b -} - -// MustSwitch_ExecuteCommandResponse_Operation invokes one of the given functions based on -// the value of x.Operation. -// -// It panics if x.Operation is nil. -func MustSwitch_ExecuteCommandResponse_Operation( - x *ExecuteCommandResponse, - caseCommandAccepted func(*ExecuteCommandResponse_CommandAccepted), - caseEventRecorded func(*ExecuteCommandResponse_EventRecorded), -) { - switch x.WhichOperation() { - case ExecuteCommandResponse_CommandAccepted_case: - caseCommandAccepted(x.GetCommandAccepted()) - case ExecuteCommandResponse_EventRecorded_case: - caseEventRecorded(x.GetEventRecorded()) - default: - panic("MustSwitch_ExecuteCommandResponse_Operation: x.Operation is not set") - } -} - -// Switch_ExecuteCommandResponse_Operation invokes one of the given functions based on -// the value of x.Operation. -// -// It calls none() if x.Operation is nil. -func Switch_ExecuteCommandResponse_Operation( - x *ExecuteCommandResponse, - caseCommandAccepted func(*ExecuteCommandResponse_CommandAccepted), - caseEventRecorded func(*ExecuteCommandResponse_EventRecorded), - none func(), -) { - switch x.WhichOperation() { - case ExecuteCommandResponse_CommandAccepted_case: - caseCommandAccepted(x.GetCommandAccepted()) - case ExecuteCommandResponse_EventRecorded_case: - caseEventRecorded(x.GetEventRecorded()) - default: - none() - } -} - -// MustMap_ExecuteCommandResponse_Operation maps x.Operation to a value of type T by invoking -// one of the given functions. -// -// It invokes the function that corresponds to the value of x.Operation, -// and returns that function's result. It panics if x.Operation is nil. -func MustMap_ExecuteCommandResponse_Operation[T any]( - x *ExecuteCommandResponse, - caseCommandAccepted func(*ExecuteCommandResponse_CommandAccepted) T, - caseEventRecorded func(*ExecuteCommandResponse_EventRecorded) T, -) T { - switch x.WhichOperation() { - case ExecuteCommandResponse_CommandAccepted_case: - return caseCommandAccepted(x.GetCommandAccepted()) - case ExecuteCommandResponse_EventRecorded_case: - return caseEventRecorded(x.GetEventRecorded()) - default: - panic("MustMap_ExecuteCommandResponse_Operation: x.Operation is not set") - } -} - -// Map_ExecuteCommandResponse_Operation maps x.Operation to a value of type T by invoking -// one of the given functions. -// -// It invokes the function that corresponds to the value of x.Operation, -// and returns that function's result. It calls none() if x.Operation is nil. -func Map_ExecuteCommandResponse_Operation[T any]( - x *ExecuteCommandResponse, - caseCommandAccepted func(*ExecuteCommandResponse_CommandAccepted) T, - caseEventRecorded func(*ExecuteCommandResponse_EventRecorded) T, - none func() T, -) T { - switch x.WhichOperation() { - case ExecuteCommandResponse_CommandAccepted_case: - return caseCommandAccepted(x.GetCommandAccepted()) - case ExecuteCommandResponse_EventRecorded_case: - return caseEventRecorded(x.GetEventRecorded()) - default: - return none() - } -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ExecuteCommandRequest) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ExecuteCommandRequest - type ExecuteCommandRequest realType - fmt.Fprintf(f, format, (*ExecuteCommandRequest)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ExecuteCommandResponse) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ExecuteCommandResponse - type ExecuteCommandResponse realType - fmt.Fprintf(f, format, (*ExecuteCommandResponse)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ExecuteCommandResponse_CommandAccepted) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ExecuteCommandResponse_CommandAccepted - type ExecuteCommandResponse_CommandAccepted realType - fmt.Fprintf(f, format, (*ExecuteCommandResponse_CommandAccepted)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ExecuteCommandResponse_EventRecorded) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ExecuteCommandResponse_EventRecorded - type ExecuteCommandResponse_EventRecorded realType - fmt.Fprintf(f, format, (*ExecuteCommandResponse_EventRecorded)(x)) -} - -// CommandExecutorAPIClientStub is a test implementation of the [CommandExecutorAPIClient] interface. -var _ CommandExecutorAPIClient = (*CommandExecutorAPIClientStub)(nil) - -type CommandExecutorAPIClientStub struct { - // ExecuteCommandFunc is a function that implements the ExecuteCommand RPC method. - ExecuteCommandFunc func(ctx context.Context, req *ExecuteCommandRequest, options ...grpc.CallOption) (CommandExecutorAPI_ExecuteCommandClient, error) -} - -// ExecuteCommand calls c.ExecuteCommandFunc if it is non-nil. Otherwise, it returns an error. -func (c *CommandExecutorAPIClientStub) ExecuteCommand(ctx context.Context, req *ExecuteCommandRequest, options ...grpc.CallOption) (CommandExecutorAPI_ExecuteCommandClient, error) { - if c.ExecuteCommandFunc == nil { - return nil, status.Error(codes.Unimplemented, "method ExecuteCommand not implemented") - } - return c.ExecuteCommandFunc(ctx, req, options...) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ExecuteCommandRequest] to implement [encoding.BinaryMarshaler]. -func (x *ExecuteCommandRequest) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ExecuteCommandRequest] to implement [encoding.BinaryUnmarshaler]. -func (x *ExecuteCommandRequest) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ExecuteCommandResponse] to implement [encoding.BinaryMarshaler]. -func (x *ExecuteCommandResponse) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ExecuteCommandResponse] to implement [encoding.BinaryUnmarshaler]. -func (x *ExecuteCommandResponse) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ExecuteCommandResponse_CommandAccepted] to implement [encoding.BinaryMarshaler]. -func (x *ExecuteCommandResponse_CommandAccepted) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ExecuteCommandResponse_CommandAccepted] to implement [encoding.BinaryUnmarshaler]. -func (x *ExecuteCommandResponse_CommandAccepted) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ExecuteCommandResponse_EventRecorded] to implement [encoding.BinaryMarshaler]. -func (x *ExecuteCommandResponse_EventRecorded) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ExecuteCommandResponse_EventRecorded] to implement [encoding.BinaryUnmarshaler]. -func (x *ExecuteCommandResponse_EventRecorded) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/grpc/messaginggrpc/doc.go b/grpc/messaginggrpc/doc.go deleted file mode 100644 index c84b0952..00000000 --- a/grpc/messaginggrpc/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package messaginggrpc defines gRPC services for interacting with the -// messages produced and consumed by hosted Dogma applications, including -// executing commands and consuming event streams. -package messaginggrpc diff --git a/grpc/messaginggrpc/errors.go b/grpc/messaginggrpc/errors.go deleted file mode 100644 index efc1301c..00000000 --- a/grpc/messaginggrpc/errors.go +++ /dev/null @@ -1,117 +0,0 @@ -package messaginggrpc - -import ( - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// UnrecognizedApplicationError returns an error indicating that the given -// application is not recognized by the server. -func UnrecognizedApplicationError(key *uuidpb.UUID) error { - s, err := status. - New(codes.NotFound, "unrecognized application"). - WithDetails( - NewUnrecognizedApplicationBuilder(). - WithApplicationKey(key). - Build(), - ) - - if err != nil { - panic(err) - } - - return s.Err() -} - -// UnrecognizedEventStreamError returns an error indicating that the given -// stream is not recognized by the server. -func UnrecognizedEventStreamError(id *uuidpb.UUID) error { - s, err := status. - New(codes.NotFound, "unrecognized event stream"). - WithDetails( - NewUnrecognizedEventStreamBuilder(). - WithEventStreamId(id). - Build(), - ) - - if err != nil { - panic(err) - } - - return s.Err() -} - -// UnrecognizedCommandTypeError returns an error indicating that the given -// command type is not recognized by the server, or is not executable within -// the target application. -func UnrecognizedCommandTypeError(id *uuidpb.UUID) error { - s, err := status. - New(codes.InvalidArgument, "unrecognized command type"). - WithDetails( - NewUnrecognizedCommandTypeBuilder(). - WithMessageTypeId(id). - Build(), - ) - - if err != nil { - panic(err) - } - - return s.Err() -} - -// UnrecognizedEventTypeError returns an error indicating that the given event -// type is not recognized by the server. -func UnrecognizedEventTypeError(id *uuidpb.UUID) error { - s, err := status. - New(codes.InvalidArgument, "unrecognized event type"). - WithDetails( - NewUnrecognizedEventTypeBuilder(). - WithMessageTypeId(id). - Build(), - ) - - if err != nil { - panic(err) - } - - return s.Err() -} - -// MalformedMessageError returns an error indicating that a message's binary -// data could not be unmarshaled as the given message type. -func MalformedMessageError(id *uuidpb.UUID) error { - s, err := status. - New(codes.InvalidArgument, "malformed message"). - WithDetails( - NewMalformedMessageBuilder(). - WithMessageTypeId(id). - Build(), - ) - - if err != nil { - panic(err) - } - - return s.Err() -} - -// InvalidMessageError returns an error indicating that a message of the given -// type failed the application's validation logic. reason is a human-readable -// description of the validation failure. -func InvalidMessageError(id *uuidpb.UUID, reason string) error { - s, err := status. - New(codes.InvalidArgument, "invalid message: "+reason). - WithDetails( - NewInvalidMessageBuilder(). - WithMessageTypeId(id). - Build(), - ) - - if err != nil { - panic(err) - } - - return s.Err() -} diff --git a/grpc/messaginggrpc/errors.pb.go b/grpc/messaginggrpc/errors.pb.go deleted file mode 100644 index 173e473f..00000000 --- a/grpc/messaginggrpc/errors.pb.go +++ /dev/null @@ -1,518 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.12 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/errors.proto - -package messaginggrpc - -import ( - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// UnrecognizedApplication is an error-details value for NOT_FOUND errors that -// occurred because a client requested an application that is unknown to the -// server. -type UnrecognizedApplication struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_ApplicationKey *uuidpb.UUID `protobuf:"bytes,1,opt,name=application_key,json=applicationKey"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UnrecognizedApplication) Reset() { - *x = UnrecognizedApplication{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UnrecognizedApplication) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnrecognizedApplication) ProtoMessage() {} - -func (x *UnrecognizedApplication) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *UnrecognizedApplication) GetApplicationKey() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_ApplicationKey - } - return nil -} - -func (x *UnrecognizedApplication) SetApplicationKey(v *uuidpb.UUID) { - x.xxx_hidden_ApplicationKey = v -} - -func (x *UnrecognizedApplication) HasApplicationKey() bool { - if x == nil { - return false - } - return x.xxx_hidden_ApplicationKey != nil -} - -func (x *UnrecognizedApplication) ClearApplicationKey() { - x.xxx_hidden_ApplicationKey = nil -} - -type UnrecognizedApplication_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // ApplicationKey is the key of the unrecognized application. - ApplicationKey *uuidpb.UUID -} - -func (b0 UnrecognizedApplication_builder) Build() *UnrecognizedApplication { - m0 := &UnrecognizedApplication{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_ApplicationKey = b.ApplicationKey - return m0 -} - -// UnrecognizedEventStream is an error-details value for NOT_FOUND errors that -// occurred because a client requested an unrecognized stream ID. -type UnrecognizedEventStream struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_EventStreamId *uuidpb.UUID `protobuf:"bytes,1,opt,name=event_stream_id,json=eventStreamId"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UnrecognizedEventStream) Reset() { - *x = UnrecognizedEventStream{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UnrecognizedEventStream) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnrecognizedEventStream) ProtoMessage() {} - -func (x *UnrecognizedEventStream) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *UnrecognizedEventStream) GetEventStreamId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_EventStreamId - } - return nil -} - -func (x *UnrecognizedEventStream) SetEventStreamId(v *uuidpb.UUID) { - x.xxx_hidden_EventStreamId = v -} - -func (x *UnrecognizedEventStream) HasEventStreamId() bool { - if x == nil { - return false - } - return x.xxx_hidden_EventStreamId != nil -} - -func (x *UnrecognizedEventStream) ClearEventStreamId() { - x.xxx_hidden_EventStreamId = nil -} - -type UnrecognizedEventStream_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // EventStreamId is the ID of the unrecognized stream. - EventStreamId *uuidpb.UUID -} - -func (b0 UnrecognizedEventStream_builder) Build() *UnrecognizedEventStream { - m0 := &UnrecognizedEventStream{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_EventStreamId = b.EventStreamId - return m0 -} - -// UnrecognizedCommandType is an error-details value for INVALID_ARGUMENT -// errors that occurred because a specific command type was not recognized by -// the server, or is not executable within the target application. -type UnrecognizedCommandType struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_MessageTypeId *uuidpb.UUID `protobuf:"bytes,1,opt,name=message_type_id,json=messageTypeId"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UnrecognizedCommandType) Reset() { - *x = UnrecognizedCommandType{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UnrecognizedCommandType) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnrecognizedCommandType) ProtoMessage() {} - -func (x *UnrecognizedCommandType) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *UnrecognizedCommandType) GetMessageTypeId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_MessageTypeId - } - return nil -} - -func (x *UnrecognizedCommandType) SetMessageTypeId(v *uuidpb.UUID) { - x.xxx_hidden_MessageTypeId = v -} - -func (x *UnrecognizedCommandType) HasMessageTypeId() bool { - if x == nil { - return false - } - return x.xxx_hidden_MessageTypeId != nil -} - -func (x *UnrecognizedCommandType) ClearMessageTypeId() { - x.xxx_hidden_MessageTypeId = nil -} - -type UnrecognizedCommandType_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // MessageTypeId is the ID of the unrecognized command type. - MessageTypeId *uuidpb.UUID -} - -func (b0 UnrecognizedCommandType_builder) Build() *UnrecognizedCommandType { - m0 := &UnrecognizedCommandType{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_MessageTypeId = b.MessageTypeId - return m0 -} - -// UnrecognizedEventType is an error-details value for INVALID_ARGUMENT errors -// that occurred because a specific event type was not recognized by the -// server. -type UnrecognizedEventType struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_MessageTypeId *uuidpb.UUID `protobuf:"bytes,1,opt,name=message_type_id,json=messageTypeId"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UnrecognizedEventType) Reset() { - *x = UnrecognizedEventType{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UnrecognizedEventType) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnrecognizedEventType) ProtoMessage() {} - -func (x *UnrecognizedEventType) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *UnrecognizedEventType) GetMessageTypeId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_MessageTypeId - } - return nil -} - -func (x *UnrecognizedEventType) SetMessageTypeId(v *uuidpb.UUID) { - x.xxx_hidden_MessageTypeId = v -} - -func (x *UnrecognizedEventType) HasMessageTypeId() bool { - if x == nil { - return false - } - return x.xxx_hidden_MessageTypeId != nil -} - -func (x *UnrecognizedEventType) ClearMessageTypeId() { - x.xxx_hidden_MessageTypeId = nil -} - -type UnrecognizedEventType_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // MessageTypeId is the ID of the unrecognized event type. - MessageTypeId *uuidpb.UUID -} - -func (b0 UnrecognizedEventType_builder) Build() *UnrecognizedEventType { - m0 := &UnrecognizedEventType{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_MessageTypeId = b.MessageTypeId - return m0 -} - -// MalformedMessage is an error-details value for INVALID_ARGUMENT errors that -// occurred because a message's binary data could not be unmarshaled. -type MalformedMessage struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_MessageTypeId *uuidpb.UUID `protobuf:"bytes,1,opt,name=message_type_id,json=messageTypeId"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MalformedMessage) Reset() { - *x = MalformedMessage{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MalformedMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MalformedMessage) ProtoMessage() {} - -func (x *MalformedMessage) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *MalformedMessage) GetMessageTypeId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_MessageTypeId - } - return nil -} - -func (x *MalformedMessage) SetMessageTypeId(v *uuidpb.UUID) { - x.xxx_hidden_MessageTypeId = v -} - -func (x *MalformedMessage) HasMessageTypeId() bool { - if x == nil { - return false - } - return x.xxx_hidden_MessageTypeId != nil -} - -func (x *MalformedMessage) ClearMessageTypeId() { - x.xxx_hidden_MessageTypeId = nil -} - -type MalformedMessage_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // MessageTypeId is the ID of the message type that the data could not be - // unmarshaled as. - MessageTypeId *uuidpb.UUID -} - -func (b0 MalformedMessage_builder) Build() *MalformedMessage { - m0 := &MalformedMessage{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_MessageTypeId = b.MessageTypeId - return m0 -} - -// InvalidMessage is an error-details value for INVALID_ARGUMENT errors that -// occurred because a message failed the application's validation logic. -type InvalidMessage struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_MessageTypeId *uuidpb.UUID `protobuf:"bytes,1,opt,name=message_type_id,json=messageTypeId"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *InvalidMessage) Reset() { - *x = InvalidMessage{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *InvalidMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InvalidMessage) ProtoMessage() {} - -func (x *InvalidMessage) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *InvalidMessage) GetMessageTypeId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_MessageTypeId - } - return nil -} - -func (x *InvalidMessage) SetMessageTypeId(v *uuidpb.UUID) { - x.xxx_hidden_MessageTypeId = v -} - -func (x *InvalidMessage) HasMessageTypeId() bool { - if x == nil { - return false - } - return x.xxx_hidden_MessageTypeId != nil -} - -func (x *InvalidMessage) ClearMessageTypeId() { - x.xxx_hidden_MessageTypeId = nil -} - -type InvalidMessage_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // MessageTypeId is the ID of the type of the invalid message. - MessageTypeId *uuidpb.UUID -} - -func (b0 InvalidMessage_builder) Build() *InvalidMessage { - m0 := &InvalidMessage{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_MessageTypeId = b.MessageTypeId - return m0 -} - -var File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_rawDesc = "" + - "\n" + - "=github.com/dogmatiq/enginekit/grpc/messaginggrpc/errors.proto\x12\x12dogma.messaging.v1\x1a8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\"X\n" + - "\x17UnrecognizedApplication\x12=\n" + - "\x0fapplication_key\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\x0eapplicationKey\"W\n" + - "\x17UnrecognizedEventStream\x12<\n" + - "\x0fevent_stream_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\reventStreamId\"W\n" + - "\x17UnrecognizedCommandType\x12<\n" + - "\x0fmessage_type_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\rmessageTypeId\"U\n" + - "\x15UnrecognizedEventType\x12<\n" + - "\x0fmessage_type_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\rmessageTypeId\"P\n" + - "\x10MalformedMessage\x12<\n" + - "\x0fmessage_type_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\rmessageTypeId\"N\n" + - "\x0eInvalidMessage\x12<\n" + - "\x0fmessage_type_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\rmessageTypeIdB2Z0github.com/dogmatiq/enginekit/grpc/messaginggrpcb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_goTypes = []any{ - (*UnrecognizedApplication)(nil), // 0: dogma.messaging.v1.UnrecognizedApplication - (*UnrecognizedEventStream)(nil), // 1: dogma.messaging.v1.UnrecognizedEventStream - (*UnrecognizedCommandType)(nil), // 2: dogma.messaging.v1.UnrecognizedCommandType - (*UnrecognizedEventType)(nil), // 3: dogma.messaging.v1.UnrecognizedEventType - (*MalformedMessage)(nil), // 4: dogma.messaging.v1.MalformedMessage - (*InvalidMessage)(nil), // 5: dogma.messaging.v1.InvalidMessage - (*uuidpb.UUID)(nil), // 6: dogma.protobuf.UUID -} -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_depIdxs = []int32{ - 6, // 0: dogma.messaging.v1.UnrecognizedApplication.application_key:type_name -> dogma.protobuf.UUID - 6, // 1: dogma.messaging.v1.UnrecognizedEventStream.event_stream_id:type_name -> dogma.protobuf.UUID - 6, // 2: dogma.messaging.v1.UnrecognizedCommandType.message_type_id:type_name -> dogma.protobuf.UUID - 6, // 3: dogma.messaging.v1.UnrecognizedEventType.message_type_id:type_name -> dogma.protobuf.UUID - 6, // 4: dogma.messaging.v1.MalformedMessage.message_type_id:type_name -> dogma.protobuf.UUID - 6, // 5: dogma.messaging.v1.InvalidMessage.message_type_id:type_name -> dogma.protobuf.UUID - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_init() } -func file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_init() { - if File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_rawDesc)), - NumEnums: 0, - NumMessages: 6, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto = out.File - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_errors_proto_depIdxs = nil -} diff --git a/grpc/messaginggrpc/errors.proto b/grpc/messaginggrpc/errors.proto deleted file mode 100644 index c06c33ea..00000000 --- a/grpc/messaginggrpc/errors.proto +++ /dev/null @@ -1,52 +0,0 @@ -edition = "2024"; -package dogma.messaging.v1; - -option go_package = "github.com/dogmatiq/enginekit/grpc/messaginggrpc"; - -import "github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto"; - -// UnrecognizedApplication is an error-details value for NOT_FOUND errors that -// occurred because a client requested an application that is unknown to the -// server. -message UnrecognizedApplication { - // ApplicationKey is the key of the unrecognized application. - dogma.protobuf.UUID application_key = 1; -} - -// UnrecognizedEventStream is an error-details value for NOT_FOUND errors that -// occurred because a client requested an unrecognized stream ID. -message UnrecognizedEventStream { - // EventStreamId is the ID of the unrecognized stream. - dogma.protobuf.UUID event_stream_id = 1; -} - -// UnrecognizedCommandType is an error-details value for INVALID_ARGUMENT -// errors that occurred because a specific command type was not recognized by -// the server, or is not executable within the target application. -message UnrecognizedCommandType { - // MessageTypeId is the ID of the unrecognized command type. - dogma.protobuf.UUID message_type_id = 1; -} - -// UnrecognizedEventType is an error-details value for INVALID_ARGUMENT errors -// that occurred because a specific event type was not recognized by the -// server. -message UnrecognizedEventType { - // MessageTypeId is the ID of the unrecognized event type. - dogma.protobuf.UUID message_type_id = 1; -} - -// MalformedMessage is an error-details value for INVALID_ARGUMENT errors that -// occurred because a message's binary data could not be unmarshaled. -message MalformedMessage { - // MessageTypeId is the ID of the message type that the data could not be - // unmarshaled as. - dogma.protobuf.UUID message_type_id = 1; -} - -// InvalidMessage is an error-details value for INVALID_ARGUMENT errors that -// occurred because a message failed the application's validation logic. -message InvalidMessage { - // MessageTypeId is the ID of the type of the invalid message. - dogma.protobuf.UUID message_type_id = 1; -} diff --git a/grpc/messaginggrpc/errors_primo.pb.go b/grpc/messaginggrpc/errors_primo.pb.go deleted file mode 100644 index 19b97d85..00000000 --- a/grpc/messaginggrpc/errors_primo.pb.go +++ /dev/null @@ -1,793 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/errors.proto - -package messaginggrpc - -import ( - "fmt" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - proto "google.golang.org/protobuf/proto" -) - -type UnrecognizedApplicationBuilder struct { - prototype UnrecognizedApplication -} - -// NewUnrecognizedApplicationBuilder returns a builder that constructs [UnrecognizedApplication] messages. -func NewUnrecognizedApplicationBuilder() *UnrecognizedApplicationBuilder { - return &UnrecognizedApplicationBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *UnrecognizedApplicationBuilder) From(x *UnrecognizedApplication) *UnrecognizedApplicationBuilder { - proto.Reset(&b.prototype) - if x.HasApplicationKey() { - b.prototype.SetApplicationKey(x.GetApplicationKey()) - } - return b -} - -// Build returns a new [UnrecognizedApplication] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *UnrecognizedApplicationBuilder) Build() *UnrecognizedApplication { - m := &UnrecognizedApplication{} - if b.prototype.HasApplicationKey() { - m.SetApplicationKey(b.prototype.GetApplicationKey()) - } - return m -} - -// WithApplicationKey configures the builder to set the ApplicationKey field to v, -// then returns b. -func (b *UnrecognizedApplicationBuilder) WithApplicationKey(v *uuidpb.UUID) *UnrecognizedApplicationBuilder { - b.prototype.SetApplicationKey(v) - return b -} - -type UnrecognizedEventStreamBuilder struct { - prototype UnrecognizedEventStream -} - -// NewUnrecognizedEventStreamBuilder returns a builder that constructs [UnrecognizedEventStream] messages. -func NewUnrecognizedEventStreamBuilder() *UnrecognizedEventStreamBuilder { - return &UnrecognizedEventStreamBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *UnrecognizedEventStreamBuilder) From(x *UnrecognizedEventStream) *UnrecognizedEventStreamBuilder { - proto.Reset(&b.prototype) - if x.HasEventStreamId() { - b.prototype.SetEventStreamId(x.GetEventStreamId()) - } - return b -} - -// Build returns a new [UnrecognizedEventStream] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *UnrecognizedEventStreamBuilder) Build() *UnrecognizedEventStream { - m := &UnrecognizedEventStream{} - if b.prototype.HasEventStreamId() { - m.SetEventStreamId(b.prototype.GetEventStreamId()) - } - return m -} - -// WithEventStreamId configures the builder to set the EventStreamId field to v, -// then returns b. -func (b *UnrecognizedEventStreamBuilder) WithEventStreamId(v *uuidpb.UUID) *UnrecognizedEventStreamBuilder { - b.prototype.SetEventStreamId(v) - return b -} - -type UnrecognizedCommandTypeBuilder struct { - prototype UnrecognizedCommandType -} - -// NewUnrecognizedCommandTypeBuilder returns a builder that constructs [UnrecognizedCommandType] messages. -func NewUnrecognizedCommandTypeBuilder() *UnrecognizedCommandTypeBuilder { - return &UnrecognizedCommandTypeBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *UnrecognizedCommandTypeBuilder) From(x *UnrecognizedCommandType) *UnrecognizedCommandTypeBuilder { - proto.Reset(&b.prototype) - if x.HasMessageTypeId() { - b.prototype.SetMessageTypeId(x.GetMessageTypeId()) - } - return b -} - -// Build returns a new [UnrecognizedCommandType] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *UnrecognizedCommandTypeBuilder) Build() *UnrecognizedCommandType { - m := &UnrecognizedCommandType{} - if b.prototype.HasMessageTypeId() { - m.SetMessageTypeId(b.prototype.GetMessageTypeId()) - } - return m -} - -// WithMessageTypeId configures the builder to set the MessageTypeId field to v, -// then returns b. -func (b *UnrecognizedCommandTypeBuilder) WithMessageTypeId(v *uuidpb.UUID) *UnrecognizedCommandTypeBuilder { - b.prototype.SetMessageTypeId(v) - return b -} - -type UnrecognizedEventTypeBuilder struct { - prototype UnrecognizedEventType -} - -// NewUnrecognizedEventTypeBuilder returns a builder that constructs [UnrecognizedEventType] messages. -func NewUnrecognizedEventTypeBuilder() *UnrecognizedEventTypeBuilder { - return &UnrecognizedEventTypeBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *UnrecognizedEventTypeBuilder) From(x *UnrecognizedEventType) *UnrecognizedEventTypeBuilder { - proto.Reset(&b.prototype) - if x.HasMessageTypeId() { - b.prototype.SetMessageTypeId(x.GetMessageTypeId()) - } - return b -} - -// Build returns a new [UnrecognizedEventType] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *UnrecognizedEventTypeBuilder) Build() *UnrecognizedEventType { - m := &UnrecognizedEventType{} - if b.prototype.HasMessageTypeId() { - m.SetMessageTypeId(b.prototype.GetMessageTypeId()) - } - return m -} - -// WithMessageTypeId configures the builder to set the MessageTypeId field to v, -// then returns b. -func (b *UnrecognizedEventTypeBuilder) WithMessageTypeId(v *uuidpb.UUID) *UnrecognizedEventTypeBuilder { - b.prototype.SetMessageTypeId(v) - return b -} - -type MalformedMessageBuilder struct { - prototype MalformedMessage -} - -// NewMalformedMessageBuilder returns a builder that constructs [MalformedMessage] messages. -func NewMalformedMessageBuilder() *MalformedMessageBuilder { - return &MalformedMessageBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *MalformedMessageBuilder) From(x *MalformedMessage) *MalformedMessageBuilder { - proto.Reset(&b.prototype) - if x.HasMessageTypeId() { - b.prototype.SetMessageTypeId(x.GetMessageTypeId()) - } - return b -} - -// Build returns a new [MalformedMessage] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *MalformedMessageBuilder) Build() *MalformedMessage { - m := &MalformedMessage{} - if b.prototype.HasMessageTypeId() { - m.SetMessageTypeId(b.prototype.GetMessageTypeId()) - } - return m -} - -// WithMessageTypeId configures the builder to set the MessageTypeId field to v, -// then returns b. -func (b *MalformedMessageBuilder) WithMessageTypeId(v *uuidpb.UUID) *MalformedMessageBuilder { - b.prototype.SetMessageTypeId(v) - return b -} - -type InvalidMessageBuilder struct { - prototype InvalidMessage -} - -// NewInvalidMessageBuilder returns a builder that constructs [InvalidMessage] messages. -func NewInvalidMessageBuilder() *InvalidMessageBuilder { - return &InvalidMessageBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *InvalidMessageBuilder) From(x *InvalidMessage) *InvalidMessageBuilder { - proto.Reset(&b.prototype) - if x.HasMessageTypeId() { - b.prototype.SetMessageTypeId(x.GetMessageTypeId()) - } - return b -} - -// Build returns a new [InvalidMessage] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *InvalidMessageBuilder) Build() *InvalidMessage { - m := &InvalidMessage{} - if b.prototype.HasMessageTypeId() { - m.SetMessageTypeId(b.prototype.GetMessageTypeId()) - } - return m -} - -// WithMessageTypeId configures the builder to set the MessageTypeId field to v, -// then returns b. -func (b *InvalidMessageBuilder) WithMessageTypeId(v *uuidpb.UUID) *InvalidMessageBuilder { - b.prototype.SetMessageTypeId(v) - return b -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *UnrecognizedApplication) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = UnrecognizedApplication - type UnrecognizedApplication realType - fmt.Fprintf(f, format, (*UnrecognizedApplication)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *UnrecognizedEventStream) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = UnrecognizedEventStream - type UnrecognizedEventStream realType - fmt.Fprintf(f, format, (*UnrecognizedEventStream)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *UnrecognizedCommandType) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = UnrecognizedCommandType - type UnrecognizedCommandType realType - fmt.Fprintf(f, format, (*UnrecognizedCommandType)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *UnrecognizedEventType) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = UnrecognizedEventType - type UnrecognizedEventType realType - fmt.Fprintf(f, format, (*UnrecognizedEventType)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *MalformedMessage) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = MalformedMessage - type MalformedMessage realType - fmt.Fprintf(f, format, (*MalformedMessage)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *InvalidMessage) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = InvalidMessage - type InvalidMessage realType - fmt.Fprintf(f, format, (*InvalidMessage)(x)) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*UnrecognizedApplication] to implement [encoding.BinaryMarshaler]. -func (x *UnrecognizedApplication) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*UnrecognizedApplication] to implement [encoding.BinaryUnmarshaler]. -func (x *UnrecognizedApplication) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*UnrecognizedEventStream] to implement [encoding.BinaryMarshaler]. -func (x *UnrecognizedEventStream) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*UnrecognizedEventStream] to implement [encoding.BinaryUnmarshaler]. -func (x *UnrecognizedEventStream) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*UnrecognizedCommandType] to implement [encoding.BinaryMarshaler]. -func (x *UnrecognizedCommandType) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*UnrecognizedCommandType] to implement [encoding.BinaryUnmarshaler]. -func (x *UnrecognizedCommandType) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*UnrecognizedEventType] to implement [encoding.BinaryMarshaler]. -func (x *UnrecognizedEventType) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*UnrecognizedEventType] to implement [encoding.BinaryUnmarshaler]. -func (x *UnrecognizedEventType) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*MalformedMessage] to implement [encoding.BinaryMarshaler]. -func (x *MalformedMessage) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*MalformedMessage] to implement [encoding.BinaryUnmarshaler]. -func (x *MalformedMessage) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*InvalidMessage] to implement [encoding.BinaryMarshaler]. -func (x *InvalidMessage) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*InvalidMessage] to implement [encoding.BinaryUnmarshaler]. -func (x *InvalidMessage) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/grpc/messaginggrpc/eventstreamconsumer.pb.go b/grpc/messaginggrpc/eventstreamconsumer.pb.go deleted file mode 100644 index cb7deef3..00000000 --- a/grpc/messaginggrpc/eventstreamconsumer.pb.go +++ /dev/null @@ -1,505 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.12 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/eventstreamconsumer.proto - -package messaginggrpc - -import ( - envelopepb "github.com/dogmatiq/enginekit/protobuf/envelopepb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// ListEventStreamsRequest is the input to the -// [EventStreamConsumerAPI.ListEventStreams] method. -type ListEventStreamsRequest struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ListEventStreamsRequest) Reset() { - *x = ListEventStreamsRequest{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ListEventStreamsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListEventStreamsRequest) ProtoMessage() {} - -func (x *ListEventStreamsRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -type ListEventStreamsRequest_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - -} - -func (b0 ListEventStreamsRequest_builder) Build() *ListEventStreamsRequest { - m0 := &ListEventStreamsRequest{} - b, x := &b0, m0 - _, _ = b, x - return m0 -} - -// ListEventStreamsResponse is the output of the -// [EventStreamConsumerAPI.ListEventStreams] method. -type ListEventStreamsResponse struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_EventStream *EventStream `protobuf:"bytes,1,opt,name=event_stream,json=eventStream"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ListEventStreamsResponse) Reset() { - *x = ListEventStreamsResponse{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ListEventStreamsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListEventStreamsResponse) ProtoMessage() {} - -func (x *ListEventStreamsResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *ListEventStreamsResponse) GetEventStream() *EventStream { - if x != nil { - return x.xxx_hidden_EventStream - } - return nil -} - -func (x *ListEventStreamsResponse) SetEventStream(v *EventStream) { - x.xxx_hidden_EventStream = v -} - -func (x *ListEventStreamsResponse) HasEventStream() bool { - if x == nil { - return false - } - return x.xxx_hidden_EventStream != nil -} - -func (x *ListEventStreamsResponse) ClearEventStream() { - x.xxx_hidden_EventStream = nil -} - -type ListEventStreamsResponse_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // EventStream is an event stream offered by the server. - EventStream *EventStream -} - -func (b0 ListEventStreamsResponse_builder) Build() *ListEventStreamsResponse { - m0 := &ListEventStreamsResponse{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_EventStream = b.EventStream - return m0 -} - -// EventStream describes an offset-based ordered event stream. -type EventStream struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_EventStreamId *uuidpb.UUID `protobuf:"bytes,1,opt,name=event_stream_id,json=eventStreamId"` - xxx_hidden_NextOffset uint64 `protobuf:"varint,2,opt,name=next_offset,json=nextOffset"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EventStream) Reset() { - *x = EventStream{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EventStream) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EventStream) ProtoMessage() {} - -func (x *EventStream) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *EventStream) GetEventStreamId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_EventStreamId - } - return nil -} - -func (x *EventStream) GetNextOffset() uint64 { - if x != nil { - return x.xxx_hidden_NextOffset - } - return 0 -} - -func (x *EventStream) SetEventStreamId(v *uuidpb.UUID) { - x.xxx_hidden_EventStreamId = v -} - -func (x *EventStream) SetNextOffset(v uint64) { - x.xxx_hidden_NextOffset = v -} - -func (x *EventStream) HasEventStreamId() bool { - if x == nil { - return false - } - return x.xxx_hidden_EventStreamId != nil -} - -func (x *EventStream) ClearEventStreamId() { - x.xxx_hidden_EventStreamId = nil -} - -type EventStream_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // EventStreamId is a unique identifier for the stream. - EventStreamId *uuidpb.UUID - // NextOffset is the offset of the next event that will be written to the - // stream. The first event in the stream is at offset zero; therefore, - // this value is equivalent to the number of events that have been written - // to the stream. - NextOffset uint64 -} - -func (b0 EventStream_builder) Build() *EventStream { - m0 := &EventStream{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_EventStreamId = b.EventStreamId - x.xxx_hidden_NextOffset = b.NextOffset - return m0 -} - -// ConsumeEventsRequest is the input to the -// [EventStreamConsumerAPI.ConsumeEvents] method. -type ConsumeEventsRequest struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_EventStreamId *uuidpb.UUID `protobuf:"bytes,1,opt,name=event_stream_id,json=eventStreamId"` - xxx_hidden_CheckpointOffset uint64 `protobuf:"varint,2,opt,name=checkpoint_offset,json=checkpointOffset"` - xxx_hidden_MessageTypeIds *[]*uuidpb.UUID `protobuf:"bytes,3,rep,name=message_type_ids,json=messageTypeIds"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ConsumeEventsRequest) Reset() { - *x = ConsumeEventsRequest{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConsumeEventsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConsumeEventsRequest) ProtoMessage() {} - -func (x *ConsumeEventsRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *ConsumeEventsRequest) GetEventStreamId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_EventStreamId - } - return nil -} - -func (x *ConsumeEventsRequest) GetCheckpointOffset() uint64 { - if x != nil { - return x.xxx_hidden_CheckpointOffset - } - return 0 -} - -func (x *ConsumeEventsRequest) GetMessageTypeIds() []*uuidpb.UUID { - if x != nil { - if x.xxx_hidden_MessageTypeIds != nil { - return *x.xxx_hidden_MessageTypeIds - } - } - return nil -} - -func (x *ConsumeEventsRequest) SetEventStreamId(v *uuidpb.UUID) { - x.xxx_hidden_EventStreamId = v -} - -func (x *ConsumeEventsRequest) SetCheckpointOffset(v uint64) { - x.xxx_hidden_CheckpointOffset = v -} - -func (x *ConsumeEventsRequest) SetMessageTypeIds(v []*uuidpb.UUID) { - x.xxx_hidden_MessageTypeIds = &v -} - -func (x *ConsumeEventsRequest) HasEventStreamId() bool { - if x == nil { - return false - } - return x.xxx_hidden_EventStreamId != nil -} - -func (x *ConsumeEventsRequest) ClearEventStreamId() { - x.xxx_hidden_EventStreamId = nil -} - -type ConsumeEventsRequest_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // EventStreamId is the ID from which events are consumed. - EventStreamId *uuidpb.UUID - // CheckpointOffset is the offset at which the consumer begins. - CheckpointOffset uint64 - // MessageTypeIds is the set of message type IDs of the event types to - // include in the responses. - MessageTypeIds []*uuidpb.UUID -} - -func (b0 ConsumeEventsRequest_builder) Build() *ConsumeEventsRequest { - m0 := &ConsumeEventsRequest{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_EventStreamId = b.EventStreamId - x.xxx_hidden_CheckpointOffset = b.CheckpointOffset - x.xxx_hidden_MessageTypeIds = &b.MessageTypeIds - return m0 -} - -// ConsumeEventsResponse is the (streaming) output of the -// [EventStreamConsumerAPI.ConsumeEvents] method. -// -// It contains all of the events that match the requested message type IDs -// specified in the [ConsumeEventsRequest], starting at the checkpoint offset up -// to, but not including, the checkpoint offset in this response. -// -// The list of events may be empty, indicating that there are no matching events -// in that range. -type ConsumeEventsResponse struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_CheckpointOffset uint64 `protobuf:"varint,1,opt,name=checkpoint_offset,json=checkpointOffset"` - xxx_hidden_Envelopes *[]*envelopepb.MultiEnvelope `protobuf:"bytes,2,rep,name=envelopes"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ConsumeEventsResponse) Reset() { - *x = ConsumeEventsResponse{} - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConsumeEventsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConsumeEventsResponse) ProtoMessage() {} - -func (x *ConsumeEventsResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *ConsumeEventsResponse) GetCheckpointOffset() uint64 { - if x != nil { - return x.xxx_hidden_CheckpointOffset - } - return 0 -} - -func (x *ConsumeEventsResponse) GetEnvelopes() []*envelopepb.MultiEnvelope { - if x != nil { - if x.xxx_hidden_Envelopes != nil { - return *x.xxx_hidden_Envelopes - } - } - return nil -} - -func (x *ConsumeEventsResponse) SetCheckpointOffset(v uint64) { - x.xxx_hidden_CheckpointOffset = v -} - -func (x *ConsumeEventsResponse) SetEnvelopes(v []*envelopepb.MultiEnvelope) { - x.xxx_hidden_Envelopes = &v -} - -type ConsumeEventsResponse_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // CheckpointOffset is the offset immediately after the range of the - // stream described by this response. - // - // After handling this and all preceding responses, the client may use - // this value as the checkpoint offset to resume consuming from the - // stream in a subsequent [ConsumeEventsRequest]. - CheckpointOffset uint64 - // Envelopes is a (possibly empty) list of multi-envelopes containing - // events at offsets between the prior checkpoint offset and the - // checkpoint offset in this response. - // - // Each envelope includes the [envelopepb.EventStreamPosition] extension. - // - // The envelopes are ordered by the offset of the events they contain. - // There is no additional relationship implied between envelopes that - // appear in the same response. - // - // The offsets of the events within this response, or even within a - // single [envelopepb.MultiEnvelope] are not necessarily contiguous. - Envelopes []*envelopepb.MultiEnvelope -} - -func (b0 ConsumeEventsResponse_builder) Build() *ConsumeEventsResponse { - m0 := &ConsumeEventsResponse{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_CheckpointOffset = b.CheckpointOffset - x.xxx_hidden_Envelopes = &b.Envelopes - return m0 -} - -var File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_rawDesc = "" + - "\n" + - "Jgithub.com/dogmatiq/enginekit/grpc/messaginggrpc/eventstreamconsumer.proto\x12\x12dogma.messaging.v1\x1a@github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto\x1a8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\"\x19\n" + - "\x17ListEventStreamsRequest\"^\n" + - "\x18ListEventStreamsResponse\x12B\n" + - "\fevent_stream\x18\x01 \x01(\v2\x1f.dogma.messaging.v1.EventStreamR\veventStream\"s\n" + - "\vEventStream\x12<\n" + - "\x0fevent_stream_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\reventStreamId\x12&\n" + - "\vnext_offset\x18\x02 \x01(\x04B\x05\xaa\x01\x02\b\x02R\n" + - "nextOffset\"\xc8\x01\n" + - "\x14ConsumeEventsRequest\x12<\n" + - "\x0fevent_stream_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\reventStreamId\x122\n" + - "\x11checkpoint_offset\x18\x02 \x01(\x04B\x05\xaa\x01\x02\b\x02R\x10checkpointOffset\x12>\n" + - "\x10message_type_ids\x18\x03 \x03(\v2\x14.dogma.protobuf.UUIDR\x0emessageTypeIds\"\x88\x01\n" + - "\x15ConsumeEventsResponse\x122\n" + - "\x11checkpoint_offset\x18\x01 \x01(\x04B\x05\xaa\x01\x02\b\x02R\x10checkpointOffset\x12;\n" + - "\tenvelopes\x18\x02 \x03(\v2\x1d.dogma.protobuf.MultiEnvelopeR\tenvelopes2\xf1\x01\n" + - "\x16EventStreamConsumerAPI\x12o\n" + - "\x10ListEventStreams\x12+.dogma.messaging.v1.ListEventStreamsRequest\x1a,.dogma.messaging.v1.ListEventStreamsResponse0\x01\x12f\n" + - "\rConsumeEvents\x12(.dogma.messaging.v1.ConsumeEventsRequest\x1a).dogma.messaging.v1.ConsumeEventsResponse0\x01B2Z0github.com/dogmatiq/enginekit/grpc/messaginggrpcb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_goTypes = []any{ - (*ListEventStreamsRequest)(nil), // 0: dogma.messaging.v1.ListEventStreamsRequest - (*ListEventStreamsResponse)(nil), // 1: dogma.messaging.v1.ListEventStreamsResponse - (*EventStream)(nil), // 2: dogma.messaging.v1.EventStream - (*ConsumeEventsRequest)(nil), // 3: dogma.messaging.v1.ConsumeEventsRequest - (*ConsumeEventsResponse)(nil), // 4: dogma.messaging.v1.ConsumeEventsResponse - (*uuidpb.UUID)(nil), // 5: dogma.protobuf.UUID - (*envelopepb.MultiEnvelope)(nil), // 6: dogma.protobuf.MultiEnvelope -} -var file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_depIdxs = []int32{ - 2, // 0: dogma.messaging.v1.ListEventStreamsResponse.event_stream:type_name -> dogma.messaging.v1.EventStream - 5, // 1: dogma.messaging.v1.EventStream.event_stream_id:type_name -> dogma.protobuf.UUID - 5, // 2: dogma.messaging.v1.ConsumeEventsRequest.event_stream_id:type_name -> dogma.protobuf.UUID - 5, // 3: dogma.messaging.v1.ConsumeEventsRequest.message_type_ids:type_name -> dogma.protobuf.UUID - 6, // 4: dogma.messaging.v1.ConsumeEventsResponse.envelopes:type_name -> dogma.protobuf.MultiEnvelope - 0, // 5: dogma.messaging.v1.EventStreamConsumerAPI.ListEventStreams:input_type -> dogma.messaging.v1.ListEventStreamsRequest - 3, // 6: dogma.messaging.v1.EventStreamConsumerAPI.ConsumeEvents:input_type -> dogma.messaging.v1.ConsumeEventsRequest - 1, // 7: dogma.messaging.v1.EventStreamConsumerAPI.ListEventStreams:output_type -> dogma.messaging.v1.ListEventStreamsResponse - 4, // 8: dogma.messaging.v1.EventStreamConsumerAPI.ConsumeEvents:output_type -> dogma.messaging.v1.ConsumeEventsResponse - 7, // [7:9] is the sub-list for method output_type - 5, // [5:7] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_init() } -func file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_init() { - if File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_rawDesc)), - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto = out.File - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_grpc_messaginggrpc_eventstreamconsumer_proto_depIdxs = nil -} diff --git a/grpc/messaginggrpc/eventstreamconsumer.proto b/grpc/messaginggrpc/eventstreamconsumer.proto deleted file mode 100644 index 5cc64143..00000000 --- a/grpc/messaginggrpc/eventstreamconsumer.proto +++ /dev/null @@ -1,103 +0,0 @@ -edition = "2024"; -package dogma.messaging.v1; - -option go_package = "github.com/dogmatiq/enginekit/grpc/messaginggrpc"; - -import "github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto"; -import "github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto"; - -// EventStreamConsumerAPI is a service for consuming event messages from -// offset-based, ordered event streams. -service EventStreamConsumerAPI { - // ListEventStreams returns the event streams offered by the server. - rpc ListEventStreams(ListEventStreamsRequest) - returns (stream ListEventStreamsResponse); - - // ConsumeEvents returns event messages from a single stream, in order, - // starting from a specific offset within an event stream. - // - // The server delivers every event at or after the requested checkpoint offset - // whose message type ID is among those in the [ConsumeEventsRequest]. If no - // such events remain in the event stream, and the server cannot produce new - // events with any of the requested message type IDs, it closes the gRPC - // stream. - // - // If the requested stream ID is not recognized the server MUST return a - // NOT_FOUND error with an attached [UnrecognizedEventStream] value. See - // [UnrecognizedEventStreamError]. - // - // If the requested offset is beyond the end of the stream an OUT_OF_RANGE - // error occurs. - rpc ConsumeEvents(ConsumeEventsRequest) - returns (stream ConsumeEventsResponse); -} - -// ListEventStreamsRequest is the input to the -// [EventStreamConsumerAPI.ListEventStreams] method. -message ListEventStreamsRequest {} - -// ListEventStreamsResponse is the output of the -// [EventStreamConsumerAPI.ListEventStreams] method. -message ListEventStreamsResponse { - // EventStream is an event stream offered by the server. - EventStream event_stream = 1; -} - -// EventStream describes an offset-based ordered event stream. -message EventStream { - // EventStreamId is a unique identifier for the stream. - dogma.protobuf.UUID event_stream_id = 1; - - // NextOffset is the offset of the next event that will be written to the - // stream. The first event in the stream is at offset zero; therefore, - // this value is equivalent to the number of events that have been written - // to the stream. - uint64 next_offset = 2 [features.field_presence = IMPLICIT]; -} - -// ConsumeEventsRequest is the input to the -// [EventStreamConsumerAPI.ConsumeEvents] method. -message ConsumeEventsRequest { - // EventStreamId is the ID from which events are consumed. - dogma.protobuf.UUID event_stream_id = 1; - - // CheckpointOffset is the offset at which the consumer begins. - uint64 checkpoint_offset = 2 [features.field_presence = IMPLICIT]; - - // MessageTypeIds is the set of message type IDs of the event types to - // include in the responses. - repeated dogma.protobuf.UUID message_type_ids = 3; -} - -// ConsumeEventsResponse is the (streaming) output of the -// [EventStreamConsumerAPI.ConsumeEvents] method. -// -// It contains all of the events that match the requested message type IDs -// specified in the [ConsumeEventsRequest], starting at the checkpoint offset up -// to, but not including, the checkpoint offset in this response. -// -// The list of events may be empty, indicating that there are no matching events -// in that range. -message ConsumeEventsResponse { - // CheckpointOffset is the offset immediately after the range of the - // stream described by this response. - // - // After handling this and all preceding responses, the client may use - // this value as the checkpoint offset to resume consuming from the - // stream in a subsequent [ConsumeEventsRequest]. - uint64 checkpoint_offset = 1 [features.field_presence = IMPLICIT]; - - // Envelopes is a (possibly empty) list of multi-envelopes containing - // events at offsets between the prior checkpoint offset and the - // checkpoint offset in this response. - // - // Each envelope includes the [envelopepb.EventStreamPosition] extension. - // - // The envelopes are ordered by the offset of the events they contain. - // There is no additional relationship implied between envelopes that - // appear in the same response. - // - // The offsets of the events within this response, or even within a - // single [envelopepb.MultiEnvelope] are not necessarily contiguous. - repeated dogma.protobuf.MultiEnvelope envelopes = 2; -} diff --git a/grpc/messaginggrpc/eventstreamconsumer_grpc.pb.go b/grpc/messaginggrpc/eventstreamconsumer_grpc.pb.go deleted file mode 100644 index 45da9513..00000000 --- a/grpc/messaginggrpc/eventstreamconsumer_grpc.pb.go +++ /dev/null @@ -1,201 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.6.2 -// - protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/eventstreamconsumer.proto - -package messaginggrpc - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - EventStreamConsumerAPI_ListEventStreams_FullMethodName = "/dogma.messaging.v1.EventStreamConsumerAPI/ListEventStreams" - EventStreamConsumerAPI_ConsumeEvents_FullMethodName = "/dogma.messaging.v1.EventStreamConsumerAPI/ConsumeEvents" -) - -// EventStreamConsumerAPIClient is the client API for EventStreamConsumerAPI service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// EventStreamConsumerAPI is a service for consuming event messages from -// offset-based, ordered event streams. -type EventStreamConsumerAPIClient interface { - // ListEventStreams returns the event streams offered by the server. - ListEventStreams(ctx context.Context, in *ListEventStreamsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ListEventStreamsResponse], error) - // ConsumeEvents returns event messages from a single stream, in order, - // starting from a specific offset within an event stream. - // - // The server delivers every event at or after the requested checkpoint offset - // whose message type ID is among those in the [ConsumeEventsRequest]. If no - // such events remain in the event stream, and the server cannot produce new - // events with any of the requested message type IDs, it closes the gRPC - // stream. - // - // If the requested stream ID is not recognized the server MUST return a - // NOT_FOUND error with an attached [UnrecognizedEventStream] value. See - // [UnrecognizedEventStreamError]. - // - // If the requested offset is beyond the end of the stream an OUT_OF_RANGE - // error occurs. - ConsumeEvents(ctx context.Context, in *ConsumeEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ConsumeEventsResponse], error) -} - -type eventStreamConsumerAPIClient struct { - cc grpc.ClientConnInterface -} - -func NewEventStreamConsumerAPIClient(cc grpc.ClientConnInterface) EventStreamConsumerAPIClient { - return &eventStreamConsumerAPIClient{cc} -} - -func (c *eventStreamConsumerAPIClient) ListEventStreams(ctx context.Context, in *ListEventStreamsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ListEventStreamsResponse], error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &EventStreamConsumerAPI_ServiceDesc.Streams[0], EventStreamConsumerAPI_ListEventStreams_FullMethodName, cOpts...) - if err != nil { - return nil, err - } - x := &grpc.GenericClientStream[ListEventStreamsRequest, ListEventStreamsResponse]{ClientStream: stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type EventStreamConsumerAPI_ListEventStreamsClient = grpc.ServerStreamingClient[ListEventStreamsResponse] - -func (c *eventStreamConsumerAPIClient) ConsumeEvents(ctx context.Context, in *ConsumeEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ConsumeEventsResponse], error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &EventStreamConsumerAPI_ServiceDesc.Streams[1], EventStreamConsumerAPI_ConsumeEvents_FullMethodName, cOpts...) - if err != nil { - return nil, err - } - x := &grpc.GenericClientStream[ConsumeEventsRequest, ConsumeEventsResponse]{ClientStream: stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type EventStreamConsumerAPI_ConsumeEventsClient = grpc.ServerStreamingClient[ConsumeEventsResponse] - -// EventStreamConsumerAPIServer is the server API for EventStreamConsumerAPI service. -// All implementations should embed UnimplementedEventStreamConsumerAPIServer -// for forward compatibility. -// -// EventStreamConsumerAPI is a service for consuming event messages from -// offset-based, ordered event streams. -type EventStreamConsumerAPIServer interface { - // ListEventStreams returns the event streams offered by the server. - ListEventStreams(*ListEventStreamsRequest, grpc.ServerStreamingServer[ListEventStreamsResponse]) error - // ConsumeEvents returns event messages from a single stream, in order, - // starting from a specific offset within an event stream. - // - // The server delivers every event at or after the requested checkpoint offset - // whose message type ID is among those in the [ConsumeEventsRequest]. If no - // such events remain in the event stream, and the server cannot produce new - // events with any of the requested message type IDs, it closes the gRPC - // stream. - // - // If the requested stream ID is not recognized the server MUST return a - // NOT_FOUND error with an attached [UnrecognizedEventStream] value. See - // [UnrecognizedEventStreamError]. - // - // If the requested offset is beyond the end of the stream an OUT_OF_RANGE - // error occurs. - ConsumeEvents(*ConsumeEventsRequest, grpc.ServerStreamingServer[ConsumeEventsResponse]) error -} - -// UnimplementedEventStreamConsumerAPIServer should be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedEventStreamConsumerAPIServer struct{} - -func (UnimplementedEventStreamConsumerAPIServer) ListEventStreams(*ListEventStreamsRequest, grpc.ServerStreamingServer[ListEventStreamsResponse]) error { - return status.Error(codes.Unimplemented, "method ListEventStreams not implemented") -} -func (UnimplementedEventStreamConsumerAPIServer) ConsumeEvents(*ConsumeEventsRequest, grpc.ServerStreamingServer[ConsumeEventsResponse]) error { - return status.Error(codes.Unimplemented, "method ConsumeEvents not implemented") -} -func (UnimplementedEventStreamConsumerAPIServer) testEmbeddedByValue() {} - -// UnsafeEventStreamConsumerAPIServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to EventStreamConsumerAPIServer will -// result in compilation errors. -type UnsafeEventStreamConsumerAPIServer interface { - mustEmbedUnimplementedEventStreamConsumerAPIServer() -} - -func RegisterEventStreamConsumerAPIServer(s grpc.ServiceRegistrar, srv EventStreamConsumerAPIServer) { - // If the following call panics, it indicates UnimplementedEventStreamConsumerAPIServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&EventStreamConsumerAPI_ServiceDesc, srv) -} - -func _EventStreamConsumerAPI_ListEventStreams_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ListEventStreamsRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(EventStreamConsumerAPIServer).ListEventStreams(m, &grpc.GenericServerStream[ListEventStreamsRequest, ListEventStreamsResponse]{ServerStream: stream}) -} - -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type EventStreamConsumerAPI_ListEventStreamsServer = grpc.ServerStreamingServer[ListEventStreamsResponse] - -func _EventStreamConsumerAPI_ConsumeEvents_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ConsumeEventsRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(EventStreamConsumerAPIServer).ConsumeEvents(m, &grpc.GenericServerStream[ConsumeEventsRequest, ConsumeEventsResponse]{ServerStream: stream}) -} - -// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. -type EventStreamConsumerAPI_ConsumeEventsServer = grpc.ServerStreamingServer[ConsumeEventsResponse] - -// EventStreamConsumerAPI_ServiceDesc is the grpc.ServiceDesc for EventStreamConsumerAPI service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var EventStreamConsumerAPI_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "dogma.messaging.v1.EventStreamConsumerAPI", - HandlerType: (*EventStreamConsumerAPIServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "ListEventStreams", - Handler: _EventStreamConsumerAPI_ListEventStreams_Handler, - ServerStreams: true, - }, - { - StreamName: "ConsumeEvents", - Handler: _EventStreamConsumerAPI_ConsumeEvents_Handler, - ServerStreams: true, - }, - }, - Metadata: "github.com/dogmatiq/enginekit/grpc/messaginggrpc/eventstreamconsumer.proto", -} diff --git a/grpc/messaginggrpc/eventstreamconsumer_primo.pb.go b/grpc/messaginggrpc/eventstreamconsumer_primo.pb.go deleted file mode 100644 index e5b2089f..00000000 --- a/grpc/messaginggrpc/eventstreamconsumer_primo.pb.go +++ /dev/null @@ -1,714 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/grpc/messaginggrpc/eventstreamconsumer.proto - -package messaginggrpc - -import ( - "context" - "fmt" - envelopepb "github.com/dogmatiq/enginekit/protobuf/envelopepb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - proto "google.golang.org/protobuf/proto" -) - -type ListEventStreamsRequestBuilder struct { - prototype ListEventStreamsRequest -} - -// NewListEventStreamsRequestBuilder returns a builder that constructs [ListEventStreamsRequest] messages. -func NewListEventStreamsRequestBuilder() *ListEventStreamsRequestBuilder { - return &ListEventStreamsRequestBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ListEventStreamsRequestBuilder) From(x *ListEventStreamsRequest) *ListEventStreamsRequestBuilder { - proto.Reset(&b.prototype) - return b -} - -// Build returns a new [ListEventStreamsRequest] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ListEventStreamsRequestBuilder) Build() *ListEventStreamsRequest { - m := &ListEventStreamsRequest{} - return m -} - -type ListEventStreamsResponseBuilder struct { - prototype ListEventStreamsResponse -} - -// NewListEventStreamsResponseBuilder returns a builder that constructs [ListEventStreamsResponse] messages. -func NewListEventStreamsResponseBuilder() *ListEventStreamsResponseBuilder { - return &ListEventStreamsResponseBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ListEventStreamsResponseBuilder) From(x *ListEventStreamsResponse) *ListEventStreamsResponseBuilder { - proto.Reset(&b.prototype) - if x.HasEventStream() { - b.prototype.SetEventStream(x.GetEventStream()) - } - return b -} - -// Build returns a new [ListEventStreamsResponse] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ListEventStreamsResponseBuilder) Build() *ListEventStreamsResponse { - m := &ListEventStreamsResponse{} - if b.prototype.HasEventStream() { - m.SetEventStream(b.prototype.GetEventStream()) - } - return m -} - -// WithEventStream configures the builder to set the EventStream field to v, -// then returns b. -func (b *ListEventStreamsResponseBuilder) WithEventStream(v *EventStream) *ListEventStreamsResponseBuilder { - b.prototype.SetEventStream(v) - return b -} - -type EventStreamBuilder struct { - prototype EventStream -} - -// NewEventStreamBuilder returns a builder that constructs [EventStream] messages. -func NewEventStreamBuilder() *EventStreamBuilder { - return &EventStreamBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *EventStreamBuilder) From(x *EventStream) *EventStreamBuilder { - proto.Reset(&b.prototype) - if x.HasEventStreamId() { - b.prototype.SetEventStreamId(x.GetEventStreamId()) - } - b.prototype.SetNextOffset(x.GetNextOffset()) - return b -} - -// Build returns a new [EventStream] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *EventStreamBuilder) Build() *EventStream { - m := &EventStream{} - if b.prototype.HasEventStreamId() { - m.SetEventStreamId(b.prototype.GetEventStreamId()) - } - m.SetNextOffset(b.prototype.GetNextOffset()) - return m -} - -// WithEventStreamId configures the builder to set the EventStreamId field to v, -// then returns b. -func (b *EventStreamBuilder) WithEventStreamId(v *uuidpb.UUID) *EventStreamBuilder { - b.prototype.SetEventStreamId(v) - return b -} - -// WithNextOffset configures the builder to set the NextOffset field to v, -// then returns b. -func (b *EventStreamBuilder) WithNextOffset(v uint64) *EventStreamBuilder { - b.prototype.SetNextOffset(v) - return b -} - -type ConsumeEventsRequestBuilder struct { - prototype ConsumeEventsRequest -} - -// NewConsumeEventsRequestBuilder returns a builder that constructs [ConsumeEventsRequest] messages. -func NewConsumeEventsRequestBuilder() *ConsumeEventsRequestBuilder { - return &ConsumeEventsRequestBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ConsumeEventsRequestBuilder) From(x *ConsumeEventsRequest) *ConsumeEventsRequestBuilder { - proto.Reset(&b.prototype) - if x.HasEventStreamId() { - b.prototype.SetEventStreamId(x.GetEventStreamId()) - } - b.prototype.SetCheckpointOffset(x.GetCheckpointOffset()) - b.prototype.SetMessageTypeIds(x.GetMessageTypeIds()) - return b -} - -// Build returns a new [ConsumeEventsRequest] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ConsumeEventsRequestBuilder) Build() *ConsumeEventsRequest { - m := &ConsumeEventsRequest{} - if b.prototype.HasEventStreamId() { - m.SetEventStreamId(b.prototype.GetEventStreamId()) - } - m.SetCheckpointOffset(b.prototype.GetCheckpointOffset()) - m.SetMessageTypeIds(b.prototype.GetMessageTypeIds()) - return m -} - -// WithEventStreamId configures the builder to set the EventStreamId field to v, -// then returns b. -func (b *ConsumeEventsRequestBuilder) WithEventStreamId(v *uuidpb.UUID) *ConsumeEventsRequestBuilder { - b.prototype.SetEventStreamId(v) - return b -} - -// WithCheckpointOffset configures the builder to set the CheckpointOffset field to v, -// then returns b. -func (b *ConsumeEventsRequestBuilder) WithCheckpointOffset(v uint64) *ConsumeEventsRequestBuilder { - b.prototype.SetCheckpointOffset(v) - return b -} - -// WithMessageTypeIds configures the builder to set the MessageTypeIds field to v, -// then returns b. -func (b *ConsumeEventsRequestBuilder) WithMessageTypeIds(v []*uuidpb.UUID) *ConsumeEventsRequestBuilder { - b.prototype.SetMessageTypeIds(v) - return b -} - -type ConsumeEventsResponseBuilder struct { - prototype ConsumeEventsResponse -} - -// NewConsumeEventsResponseBuilder returns a builder that constructs [ConsumeEventsResponse] messages. -func NewConsumeEventsResponseBuilder() *ConsumeEventsResponseBuilder { - return &ConsumeEventsResponseBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *ConsumeEventsResponseBuilder) From(x *ConsumeEventsResponse) *ConsumeEventsResponseBuilder { - proto.Reset(&b.prototype) - b.prototype.SetCheckpointOffset(x.GetCheckpointOffset()) - b.prototype.SetEnvelopes(x.GetEnvelopes()) - return b -} - -// Build returns a new [ConsumeEventsResponse] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *ConsumeEventsResponseBuilder) Build() *ConsumeEventsResponse { - m := &ConsumeEventsResponse{} - m.SetCheckpointOffset(b.prototype.GetCheckpointOffset()) - m.SetEnvelopes(b.prototype.GetEnvelopes()) - return m -} - -// WithCheckpointOffset configures the builder to set the CheckpointOffset field to v, -// then returns b. -func (b *ConsumeEventsResponseBuilder) WithCheckpointOffset(v uint64) *ConsumeEventsResponseBuilder { - b.prototype.SetCheckpointOffset(v) - return b -} - -// WithEnvelopes configures the builder to set the Envelopes field to v, -// then returns b. -func (b *ConsumeEventsResponseBuilder) WithEnvelopes(v []*envelopepb.MultiEnvelope) *ConsumeEventsResponseBuilder { - b.prototype.SetEnvelopes(v) - return b -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ListEventStreamsRequest) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ListEventStreamsRequest - type ListEventStreamsRequest realType - fmt.Fprintf(f, format, (*ListEventStreamsRequest)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ListEventStreamsResponse) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ListEventStreamsResponse - type ListEventStreamsResponse realType - fmt.Fprintf(f, format, (*ListEventStreamsResponse)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *EventStream) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = EventStream - type EventStream realType - fmt.Fprintf(f, format, (*EventStream)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ConsumeEventsRequest) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ConsumeEventsRequest - type ConsumeEventsRequest realType - fmt.Fprintf(f, format, (*ConsumeEventsRequest)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *ConsumeEventsResponse) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = ConsumeEventsResponse - type ConsumeEventsResponse realType - fmt.Fprintf(f, format, (*ConsumeEventsResponse)(x)) -} - -// EventStreamConsumerAPIClientStub is a test implementation of the [EventStreamConsumerAPIClient] interface. -var _ EventStreamConsumerAPIClient = (*EventStreamConsumerAPIClientStub)(nil) - -type EventStreamConsumerAPIClientStub struct { - // ListEventStreamsFunc is a function that implements the ListEventStreams RPC method. - ListEventStreamsFunc func(ctx context.Context, req *ListEventStreamsRequest, options ...grpc.CallOption) (EventStreamConsumerAPI_ListEventStreamsClient, error) - - // ConsumeEventsFunc is a function that implements the ConsumeEvents RPC method. - ConsumeEventsFunc func(ctx context.Context, req *ConsumeEventsRequest, options ...grpc.CallOption) (EventStreamConsumerAPI_ConsumeEventsClient, error) -} - -// ListEventStreams calls c.ListEventStreamsFunc if it is non-nil. Otherwise, it returns an error. -func (c *EventStreamConsumerAPIClientStub) ListEventStreams(ctx context.Context, req *ListEventStreamsRequest, options ...grpc.CallOption) (EventStreamConsumerAPI_ListEventStreamsClient, error) { - if c.ListEventStreamsFunc == nil { - return nil, status.Error(codes.Unimplemented, "method ListEventStreams not implemented") - } - return c.ListEventStreamsFunc(ctx, req, options...) -} - -// ConsumeEvents calls c.ConsumeEventsFunc if it is non-nil. Otherwise, it returns an error. -func (c *EventStreamConsumerAPIClientStub) ConsumeEvents(ctx context.Context, req *ConsumeEventsRequest, options ...grpc.CallOption) (EventStreamConsumerAPI_ConsumeEventsClient, error) { - if c.ConsumeEventsFunc == nil { - return nil, status.Error(codes.Unimplemented, "method ConsumeEvents not implemented") - } - return c.ConsumeEventsFunc(ctx, req, options...) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ListEventStreamsRequest] to implement [encoding.BinaryMarshaler]. -func (x *ListEventStreamsRequest) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ListEventStreamsRequest] to implement [encoding.BinaryUnmarshaler]. -func (x *ListEventStreamsRequest) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ListEventStreamsResponse] to implement [encoding.BinaryMarshaler]. -func (x *ListEventStreamsResponse) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ListEventStreamsResponse] to implement [encoding.BinaryUnmarshaler]. -func (x *ListEventStreamsResponse) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*EventStream] to implement [encoding.BinaryMarshaler]. -func (x *EventStream) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*EventStream] to implement [encoding.BinaryUnmarshaler]. -func (x *EventStream) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ConsumeEventsRequest] to implement [encoding.BinaryMarshaler]. -func (x *ConsumeEventsRequest) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ConsumeEventsRequest] to implement [encoding.BinaryUnmarshaler]. -func (x *ConsumeEventsRequest) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*ConsumeEventsResponse] to implement [encoding.BinaryMarshaler]. -func (x *ConsumeEventsResponse) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*ConsumeEventsResponse] to implement [encoding.BinaryUnmarshaler]. -func (x *ConsumeEventsResponse) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/protobuf/configpb/config.pb.go b/protobuf/configpb/config.pb.go index 80353823..386df161 100644 --- a/protobuf/configpb/config.pb.go +++ b/protobuf/configpb/config.pb.go @@ -1,13 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.11 +// protoc-gen-go v1.36.12 // protoc v6.33.1 // source: github.com/dogmatiq/enginekit/protobuf/configpb/config.proto package configpb import ( - identitypb "github.com/dogmatiq/enginekit/protobuf/identitypb" + identitypb "github.com/dogmatiq/protobuf/identitypb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -452,17 +452,17 @@ var File_github_com_dogmatiq_enginekit_protobuf_configpb_config_proto protorefle const file_github_com_dogmatiq_enginekit_protobuf_configpb_config_proto_rawDesc = "" + "\n" + - " dogma.protobuf.Identity + 7, // 0: dogma.protobuf.Application.identity:type_name -> dogma.protobuf.v1.Identity 3, // 1: dogma.protobuf.Application.handlers:type_name -> dogma.protobuf.Handler 5, // 2: dogma.protobuf.Application.messages:type_name -> dogma.protobuf.Application.MessagesEntry - 7, // 3: dogma.protobuf.Handler.identity:type_name -> dogma.protobuf.Identity + 7, // 3: dogma.protobuf.Handler.identity:type_name -> dogma.protobuf.v1.Identity 1, // 4: dogma.protobuf.Handler.type:type_name -> dogma.protobuf.HandlerType 6, // 5: dogma.protobuf.Handler.messages:type_name -> dogma.protobuf.Handler.MessagesEntry 0, // 6: dogma.protobuf.Application.MessagesEntry.value:type_name -> dogma.protobuf.MessageKind diff --git a/protobuf/configpb/config.proto b/protobuf/configpb/config.proto index e5c01f23..13053bef 100644 --- a/protobuf/configpb/config.proto +++ b/protobuf/configpb/config.proto @@ -3,7 +3,7 @@ package dogma.protobuf; option go_package = "github.com/dogmatiq/enginekit/protobuf/configpb"; -import "github.com/dogmatiq/enginekit/protobuf/identitypb/identity.proto"; +import "github.com/dogmatiq/protobuf/identitypb/identity.proto"; // MessageKind is an enumeration of the kinds of message, represented by the // [dogma.Command], [dogma.Event], and [dogma.Deadline] interfaces. @@ -28,7 +28,7 @@ enum HandlerType { // server. message Application { // Identity is the application's identity. - Identity identity = 1; + dogma.protobuf.v1.Identity identity = 1; // GoType is the fully-qualified name of the Go type that provides as the // application's implementation. @@ -45,7 +45,7 @@ message Application { // Handler is a message handler within an application. message Handler { // Identity is the handler's identity. - Identity identity = 1; + dogma.protobuf.v1.Identity identity = 1; // GoType is the fully-qualified name of the Go type that provides as the // handler's implementation. diff --git a/protobuf/configpb/config_primo.pb.go b/protobuf/configpb/config_primo.pb.go index adf9f996..3fa4408f 100644 --- a/protobuf/configpb/config_primo.pb.go +++ b/protobuf/configpb/config_primo.pb.go @@ -8,7 +8,7 @@ package configpb import ( "fmt" - identitypb "github.com/dogmatiq/enginekit/protobuf/identitypb" + identitypb "github.com/dogmatiq/protobuf/identitypb" proto "google.golang.org/protobuf/proto" ) diff --git a/protobuf/envelopepb/any.go b/protobuf/envelopepb/any.go deleted file mode 100644 index a8db53e1..00000000 --- a/protobuf/envelopepb/any.go +++ /dev/null @@ -1,72 +0,0 @@ -package envelopepb - -import ( - "fmt" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" -) - -// findAnyValue returns the first value matching T from the given sets of -// [*anypb.Any] values, searching each set in order. -func findAnyValue[ - T interface { - *E - proto.Message - }, - E any, -](sets ...[]*anypb.Any) (T, bool, error) { - var out T - - for _, values := range sets { - for _, v := range values { - if v.MessageIs(out) { - out = new(E) - return out, true, v.UnmarshalTo(out) - } - } - } - - return nil, false, nil -} - -// appendOrReplace appends value to values if there is no existing value with -// the same type URL, otherwise it replaces the existing value in place. -func appendOrReplace(values []*anypb.Any, value *anypb.Any) []*anypb.Any { - for index, existing := range values { - if existing.GetTypeUrl() == value.GetTypeUrl() { - values[index] = value - return values - } - } - - return append(values, value) -} - -// marshalAsAny returns v as an [*anypb.Any], converting it if necessary. It -// panics if x is nil, if x is an empty [*anypb.Any], or if it cannot be -// marshaled. -func marshalAsAny(x proto.Message) *anypb.Any { - if x == nil { - panic("value must not be nil") - } - - if x, ok := x.(*anypb.Any); ok { - if x.GetTypeUrl() == "" { - panic("value must not be an empty google.protobuf.Any") - } - - return x - } - - v, err := anypb.New(x) - if err != nil { - panic(fmt.Sprintf( - "unable to marshal %T as google.protobuf.Any: %s", - x, - err, - )) - } - - return v -} diff --git a/protobuf/envelopepb/baggage.go b/protobuf/envelopepb/baggage.go deleted file mode 100644 index 71d60a3f..00000000 --- a/protobuf/envelopepb/baggage.go +++ /dev/null @@ -1,72 +0,0 @@ -package envelopepb - -import ( - "fmt" - - "google.golang.org/protobuf/proto" -) - -// SetBaggage sets x as a baggage value on body. If a baggage value with the -// same type URL is already present, it is replaced. -// -// It panics if x is nil. -func SetBaggage[ - T interface { - *E - proto.Message - }, - E any, -](body *Body, x T) { - if x == nil { - panic("value must not be nil") - } - - body.SetBaggage( - appendOrReplace( - body.GetBaggage(), - marshalAsAny(x), - ), - ) -} - -// GetBaggage returns the baggage value matching T from env's baggage. -// -// Values in the envelope's body take precedence over those in its header. -// -// The second return value reports whether a baggage value of the matching type -// was present. The third return value is non-nil if the baggage value was present -// but could not be unmarshalled. -func GetBaggage[ - T interface { - *E - proto.Message - }, - E any, -](env *Envelope) (T, bool, error) { - return findAnyValue[T]( - env.GetBody().GetBaggage(), - env.GetHeader().GetBaggage(), - ) -} - -// MustGetBaggage returns the baggage value matching T from env's baggage. -// -// It panics if no baggage value of the matching type is present, or if it could -// not be unmarshalled. -func MustGetBaggage[ - T interface { - *E - proto.Message - }, - E any, -](env *Envelope) T { - x, ok, err := GetBaggage[T](env) - if err != nil { - panic(fmt.Sprintf("unable to unmarshal baggage value: %s", err)) - } - if !ok { - panic("baggage value is not present") - } - - return x -} diff --git a/protobuf/envelopepb/baggage_test.go b/protobuf/envelopepb/baggage_test.go deleted file mode 100644 index 9bc2d442..00000000 --- a/protobuf/envelopepb/baggage_test.go +++ /dev/null @@ -1,272 +0,0 @@ -package envelopepb_test - -import ( - "testing" - - . "github.com/dogmatiq/enginekit/internal/test" - . "github.com/dogmatiq/enginekit/protobuf/envelopepb" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -func TestSetBaggage(t *testing.T) { - t.Run("it adds the value to the body's baggage", func(t *testing.T) { - want, err := anypb.New(wrapperspb.String("hello")) - if err != nil { - t.Fatal(err) - } - - body := NewBodyBuilder().Build() - SetBaggage(body, wrapperspb.String("hello")) - - Expect( - t, - "unexpected baggage", - body.GetBaggage(), - []*anypb.Any{want}, - ) - }) - - t.Run("when a baggage value with the same type URL is already present", func(t *testing.T) { - t.Run("it replaces the existing value", func(t *testing.T) { - want, err := anypb.New(wrapperspb.String("second")) - if err != nil { - t.Fatal(err) - } - - body := NewBodyBuilder().Build() - SetBaggage(body, wrapperspb.String("first")) - SetBaggage(body, wrapperspb.String("second")) - - Expect( - t, - "unexpected baggage", - body.GetBaggage(), - []*anypb.Any{want}, - ) - }) - }) - - t.Run("when baggage values of other types are present", func(t *testing.T) { - t.Run("it appends the new value without disturbing the others", func(t *testing.T) { - wantInt, err := anypb.New(wrapperspb.Int64(42)) - if err != nil { - t.Fatal(err) - } - - wantString, err := anypb.New(wrapperspb.String("hello")) - if err != nil { - t.Fatal(err) - } - - body := NewBodyBuilder().Build() - SetBaggage(body, wrapperspb.Int64(42)) - SetBaggage(body, wrapperspb.String("hello")) - - Expect( - t, - "unexpected baggage", - body.GetBaggage(), - []*anypb.Any{wantInt, wantString}, - ) - }) - }) - - t.Run("when the value is nil", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - ExpectPanic( - t, - "value must not be nil", - func() { - SetBaggage[*wrapperspb.StringValue](NewBodyBuilder().Build(), nil) - }, - ) - }) - }) -} - -func TestGetBaggage(t *testing.T) { - t.Run("when a matching baggage value is present", func(t *testing.T) { - t.Run("it returns the value and true", func(t *testing.T) { - env := newEmptyEnvelope() - SetBaggage(env.GetBody(), wrapperspb.String("hello")) - - got, ok, err := GetBaggage[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find a matching baggage value") - } - - Expect( - t, - "unexpected baggage value", - got, - wrapperspb.String("hello"), - ) - }) - }) - - t.Run("when a matching baggage value is present in the header", func(t *testing.T) { - t.Run("it returns the value and true", func(t *testing.T) { - env := newEmptyEnvelope() - env.GetHeader().SetBaggage([]*anypb.Any{ - mustMarshalAny(t, wrapperspb.String("hello")), - }) - - got, ok, err := GetBaggage[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find a matching baggage value") - } - - Expect( - t, - "unexpected baggage value", - got, - wrapperspb.String("hello"), - ) - }) - }) - - t.Run("when a matching baggage value is present in both the header and the body", func(t *testing.T) { - t.Run("it returns the value from the body", func(t *testing.T) { - env := newEmptyEnvelope() - env.GetHeader().SetBaggage([]*anypb.Any{ - mustMarshalAny(t, wrapperspb.String("header")), - }) - SetBaggage(env.GetBody(), wrapperspb.String("body")) - - got, ok, err := GetBaggage[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find a matching baggage value") - } - - Expect( - t, - "unexpected baggage value", - got, - wrapperspb.String("body"), - ) - }) - }) - - t.Run("when no baggage values are present", func(t *testing.T) { - t.Run("it returns false", func(t *testing.T) { - env := newEmptyEnvelope() - - got, ok, err := GetBaggage[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if ok { - t.Fatal("expected to find no matching baggage value") - } - if got != nil { - t.Fatalf("expected nil, got %v", got) - } - }) - }) - - t.Run("when only baggage values of other types are present", func(t *testing.T) { - t.Run("it returns false", func(t *testing.T) { - env := newEmptyEnvelope() - SetBaggage(env.GetBody(), wrapperspb.Int64(42)) - - got, ok, err := GetBaggage[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if ok { - t.Fatal("expected to find no matching baggage value") - } - if got != nil { - t.Fatalf("expected nil, got %v", got) - } - }) - }) - - t.Run("when a value of the requested type has been set as an extension", func(t *testing.T) { - t.Run("it returns false (baggage and extensions are distinct)", func(t *testing.T) { - env := newEmptyEnvelope() - SetExtension(env.GetBody(), wrapperspb.String("hello")) - - _, ok, err := GetBaggage[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if ok { - t.Fatal("expected to find no matching baggage value") - } - }) - }) -} - -func TestMustGetBaggage(t *testing.T) { - t.Run("when a matching baggage value is present", func(t *testing.T) { - t.Run("it returns the value", func(t *testing.T) { - env := newEmptyEnvelope() - SetBaggage(env.GetBody(), wrapperspb.String("hello")) - - Expect( - t, - "unexpected baggage value value", - MustGetBaggage[*wrapperspb.StringValue](env), - wrapperspb.String("hello"), - ) - }) - }) - - t.Run("when no baggage values are present", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - ExpectPanic( - t, - "baggage value is not present", - func() { - MustGetBaggage[*wrapperspb.StringValue](newEmptyEnvelope()) - }, - ) - }) - }) - - t.Run("when only baggage values of other types are present", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - env := newEmptyEnvelope() - SetBaggage(env.GetBody(), wrapperspb.Int64(42)) - - ExpectPanic( - t, - "baggage value is not present", - func() { - MustGetBaggage[*wrapperspb.StringValue](env) - }, - ) - }) - }) - - t.Run("when the baggage value cannot be unmarshalled", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - env := newEmptyEnvelope() - env.GetBody().SetBaggage([]*anypb.Any{ - { - TypeUrl: "type.googleapis.com/google.protobuf.StringValue", - Value: []byte{0x0a, 0x05}, // truncated string field - }, - }) - - defer func() { - if recover() == nil { - t.Fatal("expected a panic") - } - }() - - MustGetBaggage[*wrapperspb.StringValue](env) - }) - }) -} diff --git a/protobuf/envelopepb/doc.go b/protobuf/envelopepb/doc.go deleted file mode 100644 index 5f95b1d6..00000000 --- a/protobuf/envelopepb/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package envelopepb provides the "well-known" Envelope type for representing -// message envelopes as Protocol Buffers messages. -package envelopepb diff --git a/protobuf/envelopepb/envelope.go b/protobuf/envelopepb/envelope.go deleted file mode 100644 index 154ba582..00000000 --- a/protobuf/envelopepb/envelope.go +++ /dev/null @@ -1,254 +0,0 @@ -package envelopepb - -import ( - "errors" - "fmt" - "iter" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" -) - -// Validate returns an error if x is not well-formed. -// -// Well-formedness means that all compulsory fields are populated and that no -// incompatible fields are populated. -// -// It is intentionally fairly permissive, so that message meta-data can be -// obtained even if the message is unable to be handled. -// -// It does not perform "deep" validation, such as ensuring messages, times, etc -// can be unmarshaled. -func (x *Envelope) Validate() error { - if x == nil { - return errors.New("must not be nil") - } - - header := x.GetHeader() - body := x.GetBody() - - if err := header.validate(); err != nil { - return fmt.Errorf("invalid header: %w", err) - } - - if err := body.validate(header); err != nil { - return fmt.Errorf("invalid body: %w", err) - } - - return nil -} - -// AsMultiEnvelope returns a [MultiEnvelope] that contains the same header and -// body as x. -// -// This is a convenience method for when you want to treat a single-envelope -// message as a multi-envelope message. -func (x *Envelope) AsMultiEnvelope() *MultiEnvelope { - return NewMultiEnvelopeBuilder(). - WithHeader(x.GetHeader()). - WithBodies([]*Body{x.GetBody()}). - Build() -} - -// Validate returns an error if x is not well-formed. -// -// Well-formedness means that all compulsory fields are populated and that no -// incompatible fields are populated. -// -// It is intentionally fairly permissive, so that message meta-data can be -// obtained even if the message is unable to be handled. -// -// It does not perform "deep" validation, such as ensuring messages, times, etc -// can be unmarshaled. -func (x *MultiEnvelope) Validate() error { - if x == nil { - return errors.New("must not be nil") - } - - header := x.GetHeader() - - if err := header.validate(); err != nil { - return fmt.Errorf("invalid header: %w", err) - } - - for i, b := range x.GetBodies() { - if err := b.validate(header); err != nil { - return fmt.Errorf("invalid body at index %d: %w", i, err) - } - } - - return nil -} - -// All returns an iterator over each message in x as a standalone [Envelope]. -func (x *MultiEnvelope) All() iter.Seq[*Envelope] { - return func(yield func(*Envelope) bool) { - for _, b := range x.GetBodies() { - env := NewEnvelopeBuilder(). - WithHeader(x.GetHeader()). - WithBody(b). - Build() - - if !yield(env) { - return - } - } - } -} - -// AppendBodies appends the given bodies to x. -func (x *MultiEnvelope) AppendBodies(bodies ...*Body) { - x.SetBodies( - append( - x.GetBodies(), - bodies..., - ), - ) -} - -// TryAppendEnvelope attempts to append the body from the given envelope to x. -// -// It requires that x and env share equivalent headers. If they do not, it -// returns false and does not modify x. -func (x *MultiEnvelope) TryAppendEnvelope(env *Envelope) bool { - if proto.Equal(x.GetHeader(), env.GetHeader()) { - x.AppendBodies(env.GetBody()) - return true - } - return false -} - -// validate returns an error if x is not well-formed. -func (x *Source) validate() error { - if x == nil { - return errors.New("must not be nil") - } - - if x.HasSite() { - if err := x.GetSite().Validate(); err != nil { - return fmt.Errorf("invalid site (%s): %w", x.GetSite(), err) - } - } - - if err := x.GetApplication().Validate(); err != nil { - return fmt.Errorf("invalid application (%s): %w", x.GetApplication(), err) - } - - if id := x.GetHandler(); id != nil { - if err := id.Validate(); err != nil { - return fmt.Errorf("invalid handler (%s): %w", id, err) - } - } else if x.GetInstanceId() != "" { - return errors.New("invalid instance ID: must not be specified without a handler") - } - - return nil -} - -// validate returns an error if x is not well-formed. -func (x *Message) validate() error { - if x == nil { - return errors.New("must not be nil") - } - - if err := x.GetTypeId().Validate(); err != nil { - return fmt.Errorf("invalid type ID (%s): %w", x.GetTypeId(), err) - } - - if x.GetDescription() == "" { - return errors.New("invalid description: must not be empty") - } - - // Note, x.Data may be empty. A specific application's marshaling logic could - // conceivably have a message with no data where the message type is - // sufficient information. - - return nil -} - -// validate returns an error if x is not well-formed. -func (x *Header) validate() error { - if x == nil { - return errors.New("must not be nil") - } - - if err := x.GetCausationId().Validate(); err != nil { - return fmt.Errorf("invalid causation ID (%s): %w", x.GetCausationId(), err) - } - - if err := x.GetCorrelationId().Validate(); err != nil { - return fmt.Errorf("invalid correlation ID (%s): %w", x.GetCorrelationId(), err) - } - - if err := x.GetSource().validate(); err != nil { - return fmt.Errorf("invalid source: %w", err) - } - - if err := validateAnyValues("extensions", x.GetExtensions()); err != nil { - return err - } - - if err := validateAnyValues("baggage", x.GetBaggage()); err != nil { - return err - } - - return nil -} - -// validate returns an error if x is not well-formed. -func (x *Body) validate(header *Header) error { - if x == nil { - return errors.New("must not be nil") - } - - if err := x.GetMessageId().Validate(); err != nil { - return fmt.Errorf("invalid message ID (%s): %w", x.GetMessageId(), err) - } - - if err := x.GetCreatedAt().CheckValid(); err != nil { - return fmt.Errorf("invalid created-at time: %w", err) - } - - if x.HasScheduledFor() { - if err := x.GetScheduledFor().CheckValid(); err != nil { - return fmt.Errorf("invalid scheduled-for time: %w", err) - } - - source := header.GetSource() - if source.GetHandler() == nil || source.GetInstanceId() == "" { - return errors.New("invalid scheduled-for time: must not be specified without a source handler and instance ID") - } - } - - if err := x.GetMessage().validate(); err != nil { - return fmt.Errorf("invalid message: %w", err) - } - - if err := validateAnyValues("extensions", x.GetExtensions()); err != nil { - return err - } - - if err := validateAnyValues("baggage", x.GetBaggage()); err != nil { - return err - } - - return nil -} - -func validateAnyValues(name string, values []*anypb.Any) error { - for i, v := range values { - if err := validateAnyValue(v); err != nil { - return fmt.Errorf("invalid %s at index %d: %w", name, i, err) - } - } - - return nil -} - -func validateAnyValue(v *anypb.Any) error { - if v.GetTypeUrl() == "" { - return errors.New("type URL must not be empty") - } - - return nil -} diff --git a/protobuf/envelopepb/envelope.pb.go b/protobuf/envelopepb/envelope.pb.go deleted file mode 100644 index af337587..00000000 --- a/protobuf/envelopepb/envelope.pb.go +++ /dev/null @@ -1,946 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.11 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto - -package envelopepb - -import ( - identitypb "github.com/dogmatiq/enginekit/protobuf/identitypb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Envelope is a container for a Dogma message and its meta-data. -// -// It is wire-compatible with [MultiEnvelope]. -type Envelope struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Header *Header `protobuf:"bytes,1,opt,name=header"` - xxx_hidden_Body *Body `protobuf:"bytes,2,opt,name=body"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Envelope) Reset() { - *x = Envelope{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Envelope) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Envelope) ProtoMessage() {} - -func (x *Envelope) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *Envelope) GetHeader() *Header { - if x != nil { - return x.xxx_hidden_Header - } - return nil -} - -func (x *Envelope) GetBody() *Body { - if x != nil { - return x.xxx_hidden_Body - } - return nil -} - -func (x *Envelope) SetHeader(v *Header) { - x.xxx_hidden_Header = v -} - -func (x *Envelope) SetBody(v *Body) { - x.xxx_hidden_Body = v -} - -func (x *Envelope) HasHeader() bool { - if x == nil { - return false - } - return x.xxx_hidden_Header != nil -} - -func (x *Envelope) HasBody() bool { - if x == nil { - return false - } - return x.xxx_hidden_Body != nil -} - -func (x *Envelope) ClearHeader() { - x.xxx_hidden_Header = nil -} - -func (x *Envelope) ClearBody() { - x.xxx_hidden_Body = nil -} - -type Envelope_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - Header *Header - Body *Body -} - -func (b0 Envelope_builder) Build() *Envelope { - m0 := &Envelope{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_Header = b.Header - x.xxx_hidden_Body = b.Body - return m0 -} - -// MultiEnvelope is an efficient encoding of an ordered sequence of [Envelope] -// values that share common header context. -type MultiEnvelope struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Header *Header `protobuf:"bytes,1,opt,name=header"` - xxx_hidden_Bodies *[]*Body `protobuf:"bytes,2,rep,name=bodies"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MultiEnvelope) Reset() { - *x = MultiEnvelope{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MultiEnvelope) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MultiEnvelope) ProtoMessage() {} - -func (x *MultiEnvelope) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *MultiEnvelope) GetHeader() *Header { - if x != nil { - return x.xxx_hidden_Header - } - return nil -} - -func (x *MultiEnvelope) GetBodies() []*Body { - if x != nil { - if x.xxx_hidden_Bodies != nil { - return *x.xxx_hidden_Bodies - } - } - return nil -} - -func (x *MultiEnvelope) SetHeader(v *Header) { - x.xxx_hidden_Header = v -} - -func (x *MultiEnvelope) SetBodies(v []*Body) { - x.xxx_hidden_Bodies = &v -} - -func (x *MultiEnvelope) HasHeader() bool { - if x == nil { - return false - } - return x.xxx_hidden_Header != nil -} - -func (x *MultiEnvelope) ClearHeader() { - x.xxx_hidden_Header = nil -} - -type MultiEnvelope_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - Header *Header - Bodies []*Body -} - -func (b0 MultiEnvelope_builder) Build() *MultiEnvelope { - m0 := &MultiEnvelope{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_Header = b.Header - x.xxx_hidden_Bodies = &b.Bodies - return m0 -} - -// Source identifies where a message originated. -type Source struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Site *identitypb.Identity `protobuf:"bytes,1,opt,name=site"` - xxx_hidden_Application *identitypb.Identity `protobuf:"bytes,2,opt,name=application"` - xxx_hidden_Handler *identitypb.Identity `protobuf:"bytes,3,opt,name=handler"` - xxx_hidden_InstanceId string `protobuf:"bytes,4,opt,name=instance_id,json=instanceId"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Source) Reset() { - *x = Source{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Source) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Source) ProtoMessage() {} - -func (x *Source) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *Source) GetSite() *identitypb.Identity { - if x != nil { - return x.xxx_hidden_Site - } - return nil -} - -func (x *Source) GetApplication() *identitypb.Identity { - if x != nil { - return x.xxx_hidden_Application - } - return nil -} - -func (x *Source) GetHandler() *identitypb.Identity { - if x != nil { - return x.xxx_hidden_Handler - } - return nil -} - -func (x *Source) GetInstanceId() string { - if x != nil { - return x.xxx_hidden_InstanceId - } - return "" -} - -func (x *Source) SetSite(v *identitypb.Identity) { - x.xxx_hidden_Site = v -} - -func (x *Source) SetApplication(v *identitypb.Identity) { - x.xxx_hidden_Application = v -} - -func (x *Source) SetHandler(v *identitypb.Identity) { - x.xxx_hidden_Handler = v -} - -func (x *Source) SetInstanceId(v string) { - x.xxx_hidden_InstanceId = v -} - -func (x *Source) HasSite() bool { - if x == nil { - return false - } - return x.xxx_hidden_Site != nil -} - -func (x *Source) HasApplication() bool { - if x == nil { - return false - } - return x.xxx_hidden_Application != nil -} - -func (x *Source) HasHandler() bool { - if x == nil { - return false - } - return x.xxx_hidden_Handler != nil -} - -func (x *Source) ClearSite() { - x.xxx_hidden_Site = nil -} - -func (x *Source) ClearApplication() { - x.xxx_hidden_Application = nil -} - -func (x *Source) ClearHandler() { - x.xxx_hidden_Handler = nil -} - -type Source_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // Site is the (optional) identity of the "site" that the source - // application is running within. - // - // The site is used to disambiguate between messages from different - // installations of the same application. - Site *identitypb.Identity - // Application is the identity of the Dogma application that produced the - // message. - Application *identitypb.Identity - // Handler is the identity of the Dogma handler that produced the message. - // - // It is the zero-value if the message was not produced by a handler. - Handler *identitypb.Identity - // InstanceId is the ID of the aggregate or process instance that produced - // the message. - // - // It is empty if the message was not produced by an aggregate or process - // handler. - InstanceId string -} - -func (b0 Source_builder) Build() *Source { - m0 := &Source{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_Site = b.Site - x.xxx_hidden_Application = b.Application - x.xxx_hidden_Handler = b.Handler - x.xxx_hidden_InstanceId = b.InstanceId - return m0 -} - -// Message is the serialized representation of a [dogma.Message]. -type Message struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_TypeId *uuidpb.UUID `protobuf:"bytes,1,opt,name=type_id,json=typeId"` - xxx_hidden_Description string `protobuf:"bytes,2,opt,name=description"` - xxx_hidden_Data []byte `protobuf:"bytes,3,opt,name=data"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Message) Reset() { - *x = Message{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Message) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Message) ProtoMessage() {} - -func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *Message) GetTypeId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_TypeId - } - return nil -} - -func (x *Message) GetDescription() string { - if x != nil { - return x.xxx_hidden_Description - } - return "" -} - -func (x *Message) GetData() []byte { - if x != nil { - return x.xxx_hidden_Data - } - return nil -} - -func (x *Message) SetTypeId(v *uuidpb.UUID) { - x.xxx_hidden_TypeId = v -} - -func (x *Message) SetDescription(v string) { - x.xxx_hidden_Description = v -} - -func (x *Message) SetData(v []byte) { - if v == nil { - v = []byte{} - } - x.xxx_hidden_Data = v -} - -func (x *Message) HasTypeId() bool { - if x == nil { - return false - } - return x.xxx_hidden_TypeId != nil -} - -func (x *Message) ClearTypeId() { - x.xxx_hidden_TypeId = nil -} - -type Message_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // TypeId is a unique identifier for the type of message, as per the Dogma - // message type registry. - TypeId *uuidpb.UUID - // Description is a human-readable description of the message, as returned by - // the [dogma.Message.MessageDescription] method. - Description string - // Data is the binary message data obtained by calling - // [dogma.Message.MarshalBinary] on the message. - Data []byte -} - -func (b0 Message_builder) Build() *Message { - m0 := &Message{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_TypeId = b.TypeId - x.xxx_hidden_Description = b.Description - x.xxx_hidden_Data = b.Data - return m0 -} - -type Header struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_CausationId *uuidpb.UUID `protobuf:"bytes,1,opt,name=causation_id,json=causationId"` - xxx_hidden_CorrelationId *uuidpb.UUID `protobuf:"bytes,2,opt,name=correlation_id,json=correlationId"` - xxx_hidden_Source *Source `protobuf:"bytes,3,opt,name=source"` - xxx_hidden_Extensions *[]*anypb.Any `protobuf:"bytes,4,rep,name=extensions"` - xxx_hidden_Baggage *[]*anypb.Any `protobuf:"bytes,5,rep,name=baggage"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Header) Reset() { - *x = Header{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Header) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Header) ProtoMessage() {} - -func (x *Header) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *Header) GetCausationId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_CausationId - } - return nil -} - -func (x *Header) GetCorrelationId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_CorrelationId - } - return nil -} - -func (x *Header) GetSource() *Source { - if x != nil { - return x.xxx_hidden_Source - } - return nil -} - -func (x *Header) GetExtensions() []*anypb.Any { - if x != nil { - if x.xxx_hidden_Extensions != nil { - return *x.xxx_hidden_Extensions - } - } - return nil -} - -func (x *Header) GetBaggage() []*anypb.Any { - if x != nil { - if x.xxx_hidden_Baggage != nil { - return *x.xxx_hidden_Baggage - } - } - return nil -} - -func (x *Header) SetCausationId(v *uuidpb.UUID) { - x.xxx_hidden_CausationId = v -} - -func (x *Header) SetCorrelationId(v *uuidpb.UUID) { - x.xxx_hidden_CorrelationId = v -} - -func (x *Header) SetSource(v *Source) { - x.xxx_hidden_Source = v -} - -func (x *Header) SetExtensions(v []*anypb.Any) { - x.xxx_hidden_Extensions = &v -} - -func (x *Header) SetBaggage(v []*anypb.Any) { - x.xxx_hidden_Baggage = &v -} - -func (x *Header) HasCausationId() bool { - if x == nil { - return false - } - return x.xxx_hidden_CausationId != nil -} - -func (x *Header) HasCorrelationId() bool { - if x == nil { - return false - } - return x.xxx_hidden_CorrelationId != nil -} - -func (x *Header) HasSource() bool { - if x == nil { - return false - } - return x.xxx_hidden_Source != nil -} - -func (x *Header) ClearCausationId() { - x.xxx_hidden_CausationId = nil -} - -func (x *Header) ClearCorrelationId() { - x.xxx_hidden_CorrelationId = nil -} - -func (x *Header) ClearSource() { - x.xxx_hidden_Source = nil -} - -type Header_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // CausationId is the (optional) ID of the message that was the direct cause - // of the messages. - // - // If it is the zero-value, the messages were not caused by any other - // message. - CausationId *uuidpb.UUID - // CorrelationId is the (optional) ID of the first ancestor of the messages - // that was itself not caused by another message, that is, it's the root of - // the message chain that ultimately resulted in these messages. - // - // If it is the zero-value, the messages were not caused by any other - // message. - CorrelationId *uuidpb.UUID - // Source identifies the origin of the messages. - Source *Source - // Extensions is a set of extension values associated with the messages, - // their causal chain, or the envelope itself. - Extensions []*anypb.Any - // Baggage is a set of extension values that are propagated through the - // entire causal chain of messages. - Baggage []*anypb.Any -} - -func (b0 Header_builder) Build() *Header { - m0 := &Header{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_CausationId = b.CausationId - x.xxx_hidden_CorrelationId = b.CorrelationId - x.xxx_hidden_Source = b.Source - x.xxx_hidden_Extensions = &b.Extensions - x.xxx_hidden_Baggage = &b.Baggage - return m0 -} - -// Body contains the metadata and encoded form of a single message in an -// [Envelope] or [MultiEnvelope]. -type Body struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_MessageId *uuidpb.UUID `protobuf:"bytes,1,opt,name=message_id,json=messageId"` - xxx_hidden_IdempotencyKey string `protobuf:"bytes,2,opt,name=idempotency_key,json=idempotencyKey"` - xxx_hidden_CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt"` - xxx_hidden_ScheduledFor *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=scheduled_for,json=scheduledFor"` - xxx_hidden_Message *Message `protobuf:"bytes,5,opt,name=message"` - xxx_hidden_Extensions *[]*anypb.Any `protobuf:"bytes,6,rep,name=extensions"` - xxx_hidden_Baggage *[]*anypb.Any `protobuf:"bytes,7,rep,name=baggage"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Body) Reset() { - *x = Body{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Body) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Body) ProtoMessage() {} - -func (x *Body) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *Body) GetMessageId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_MessageId - } - return nil -} - -func (x *Body) GetIdempotencyKey() string { - if x != nil { - return x.xxx_hidden_IdempotencyKey - } - return "" -} - -func (x *Body) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.xxx_hidden_CreatedAt - } - return nil -} - -func (x *Body) GetScheduledFor() *timestamppb.Timestamp { - if x != nil { - return x.xxx_hidden_ScheduledFor - } - return nil -} - -func (x *Body) GetMessage() *Message { - if x != nil { - return x.xxx_hidden_Message - } - return nil -} - -func (x *Body) GetExtensions() []*anypb.Any { - if x != nil { - if x.xxx_hidden_Extensions != nil { - return *x.xxx_hidden_Extensions - } - } - return nil -} - -func (x *Body) GetBaggage() []*anypb.Any { - if x != nil { - if x.xxx_hidden_Baggage != nil { - return *x.xxx_hidden_Baggage - } - } - return nil -} - -func (x *Body) SetMessageId(v *uuidpb.UUID) { - x.xxx_hidden_MessageId = v -} - -func (x *Body) SetIdempotencyKey(v string) { - x.xxx_hidden_IdempotencyKey = v -} - -func (x *Body) SetCreatedAt(v *timestamppb.Timestamp) { - x.xxx_hidden_CreatedAt = v -} - -func (x *Body) SetScheduledFor(v *timestamppb.Timestamp) { - x.xxx_hidden_ScheduledFor = v -} - -func (x *Body) SetMessage(v *Message) { - x.xxx_hidden_Message = v -} - -func (x *Body) SetExtensions(v []*anypb.Any) { - x.xxx_hidden_Extensions = &v -} - -func (x *Body) SetBaggage(v []*anypb.Any) { - x.xxx_hidden_Baggage = &v -} - -func (x *Body) HasMessageId() bool { - if x == nil { - return false - } - return x.xxx_hidden_MessageId != nil -} - -func (x *Body) HasCreatedAt() bool { - if x == nil { - return false - } - return x.xxx_hidden_CreatedAt != nil -} - -func (x *Body) HasScheduledFor() bool { - if x == nil { - return false - } - return x.xxx_hidden_ScheduledFor != nil -} - -func (x *Body) HasMessage() bool { - if x == nil { - return false - } - return x.xxx_hidden_Message != nil -} - -func (x *Body) ClearMessageId() { - x.xxx_hidden_MessageId = nil -} - -func (x *Body) ClearCreatedAt() { - x.xxx_hidden_CreatedAt = nil -} - -func (x *Body) ClearScheduledFor() { - x.xxx_hidden_ScheduledFor = nil -} - -func (x *Body) ClearMessage() { - x.xxx_hidden_Message = nil -} - -type Body_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // MessageId is a unique identifier for the message in this envelope. - MessageId *uuidpb.UUID - // IdempotencyKey is an application-defined value used to identify a command - // across retries. - // - // It is the zero-value if the message is not a command, or if the producer - // of the message did not provide an idempotency key. - IdempotencyKey string - // CreatedAt is the time at which the envelope was created. - // - // This is typically the point at which the message first enters the engine. - CreatedAt *timestamppb.Timestamp - // ScheduledFor is the time at which a deadline is reached. - // - // It is the zero-value if the message is a command or event. - ScheduledFor *timestamppb.Timestamp - // Message is the encoded representation of the [dogma.Message]. - Message *Message - // Extensions is a set of extension values associated with this message. - // - // Any values in [Header.Extensions] are overridden by values in this field - // that have the same type URL. - Extensions []*anypb.Any - // Baggage is a set of extension values associated with this message and/or - // its causal chain. - // - // Any values in [Header.Baggage] are overridden by values in this field - // that have the same type URL. - Baggage []*anypb.Any -} - -func (b0 Body_builder) Build() *Body { - m0 := &Body{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_MessageId = b.MessageId - x.xxx_hidden_IdempotencyKey = b.IdempotencyKey - x.xxx_hidden_CreatedAt = b.CreatedAt - x.xxx_hidden_ScheduledFor = b.ScheduledFor - x.xxx_hidden_Message = b.Message - x.xxx_hidden_Extensions = &b.Extensions - x.xxx_hidden_Baggage = &b.Baggage - return m0 -} - -var File_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_rawDesc = "" + - "\n" + - "@github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto\x12\x0edogma.protobuf\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19google/protobuf/any.proto\x1a@github.com/dogmatiq/enginekit/protobuf/identitypb/identity.proto\x1a8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\"d\n" + - "\bEnvelope\x12.\n" + - "\x06header\x18\x01 \x01(\v2\x16.dogma.protobuf.HeaderR\x06header\x12(\n" + - "\x04body\x18\x02 \x01(\v2\x14.dogma.protobuf.BodyR\x04body\"m\n" + - "\rMultiEnvelope\x12.\n" + - "\x06header\x18\x01 \x01(\v2\x16.dogma.protobuf.HeaderR\x06header\x12,\n" + - "\x06bodies\x18\x02 \x03(\v2\x14.dogma.protobuf.BodyR\x06bodies\"\xce\x01\n" + - "\x06Source\x12,\n" + - "\x04site\x18\x01 \x01(\v2\x18.dogma.protobuf.IdentityR\x04site\x12:\n" + - "\vapplication\x18\x02 \x01(\v2\x18.dogma.protobuf.IdentityR\vapplication\x122\n" + - "\ahandler\x18\x03 \x01(\v2\x18.dogma.protobuf.IdentityR\ahandler\x12&\n" + - "\vinstance_id\x18\x04 \x01(\tB\x05\xaa\x01\x02\b\x02R\n" + - "instanceId\"|\n" + - "\aMessage\x12-\n" + - "\atype_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\x06typeId\x12'\n" + - "\vdescription\x18\x02 \x01(\tB\x05\xaa\x01\x02\b\x02R\vdescription\x12\x19\n" + - "\x04data\x18\x03 \x01(\fB\x05\xaa\x01\x02\b\x02R\x04data\"\x94\x02\n" + - "\x06Header\x127\n" + - "\fcausation_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\vcausationId\x12;\n" + - "\x0ecorrelation_id\x18\x02 \x01(\v2\x14.dogma.protobuf.UUIDR\rcorrelationId\x12.\n" + - "\x06source\x18\x03 \x01(\v2\x16.dogma.protobuf.SourceR\x06source\x124\n" + - "\n" + - "extensions\x18\x04 \x03(\v2\x14.google.protobuf.AnyR\n" + - "extensions\x12.\n" + - "\abaggage\x18\x05 \x03(\v2\x14.google.protobuf.AnyR\abaggage\"\x80\x03\n" + - "\x04Body\x123\n" + - "\n" + - "message_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\tmessageId\x12.\n" + - "\x0fidempotency_key\x18\x02 \x01(\tB\x05\xaa\x01\x02\b\x02R\x0eidempotencyKey\x129\n" + - "\n" + - "created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12?\n" + - "\rscheduled_for\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\fscheduledFor\x121\n" + - "\amessage\x18\x05 \x01(\v2\x17.dogma.protobuf.MessageR\amessage\x124\n" + - "\n" + - "extensions\x18\x06 \x03(\v2\x14.google.protobuf.AnyR\n" + - "extensions\x12.\n" + - "\abaggage\x18\a \x03(\v2\x14.google.protobuf.AnyR\abaggageB3Z1github.com/dogmatiq/enginekit/protobuf/envelopepbb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_goTypes = []any{ - (*Envelope)(nil), // 0: dogma.protobuf.Envelope - (*MultiEnvelope)(nil), // 1: dogma.protobuf.MultiEnvelope - (*Source)(nil), // 2: dogma.protobuf.Source - (*Message)(nil), // 3: dogma.protobuf.Message - (*Header)(nil), // 4: dogma.protobuf.Header - (*Body)(nil), // 5: dogma.protobuf.Body - (*identitypb.Identity)(nil), // 6: dogma.protobuf.Identity - (*uuidpb.UUID)(nil), // 7: dogma.protobuf.UUID - (*anypb.Any)(nil), // 8: google.protobuf.Any - (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp -} -var file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_depIdxs = []int32{ - 4, // 0: dogma.protobuf.Envelope.header:type_name -> dogma.protobuf.Header - 5, // 1: dogma.protobuf.Envelope.body:type_name -> dogma.protobuf.Body - 4, // 2: dogma.protobuf.MultiEnvelope.header:type_name -> dogma.protobuf.Header - 5, // 3: dogma.protobuf.MultiEnvelope.bodies:type_name -> dogma.protobuf.Body - 6, // 4: dogma.protobuf.Source.site:type_name -> dogma.protobuf.Identity - 6, // 5: dogma.protobuf.Source.application:type_name -> dogma.protobuf.Identity - 6, // 6: dogma.protobuf.Source.handler:type_name -> dogma.protobuf.Identity - 7, // 7: dogma.protobuf.Message.type_id:type_name -> dogma.protobuf.UUID - 7, // 8: dogma.protobuf.Header.causation_id:type_name -> dogma.protobuf.UUID - 7, // 9: dogma.protobuf.Header.correlation_id:type_name -> dogma.protobuf.UUID - 2, // 10: dogma.protobuf.Header.source:type_name -> dogma.protobuf.Source - 8, // 11: dogma.protobuf.Header.extensions:type_name -> google.protobuf.Any - 8, // 12: dogma.protobuf.Header.baggage:type_name -> google.protobuf.Any - 7, // 13: dogma.protobuf.Body.message_id:type_name -> dogma.protobuf.UUID - 9, // 14: dogma.protobuf.Body.created_at:type_name -> google.protobuf.Timestamp - 9, // 15: dogma.protobuf.Body.scheduled_for:type_name -> google.protobuf.Timestamp - 3, // 16: dogma.protobuf.Body.message:type_name -> dogma.protobuf.Message - 8, // 17: dogma.protobuf.Body.extensions:type_name -> google.protobuf.Any - 8, // 18: dogma.protobuf.Body.baggage:type_name -> google.protobuf.Any - 19, // [19:19] is the sub-list for method output_type - 19, // [19:19] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_init() } -func file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_init() { - if File_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_rawDesc)), - NumEnums: 0, - NumMessages: 6, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto = out.File - file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_protobuf_envelopepb_envelope_proto_depIdxs = nil -} diff --git a/protobuf/envelopepb/envelope.proto b/protobuf/envelopepb/envelope.proto deleted file mode 100644 index 527c66a7..00000000 --- a/protobuf/envelopepb/envelope.proto +++ /dev/null @@ -1,134 +0,0 @@ -edition = "2024"; -package dogma.protobuf; - -option go_package = "github.com/dogmatiq/enginekit/protobuf/envelopepb"; - -import "google/protobuf/timestamp.proto"; -import "google/protobuf/any.proto"; -import "github.com/dogmatiq/enginekit/protobuf/identitypb/identity.proto"; -import "github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto"; - -// Envelope is a container for a Dogma message and its meta-data. -// -// It is wire-compatible with [MultiEnvelope]. -message Envelope { - Header header = 1; - Body body = 2; -} - -// MultiEnvelope is an efficient encoding of an ordered sequence of [Envelope] -// values that share common header context. -// -message MultiEnvelope { - Header header = 1; - repeated Body bodies = 2; -} - -// Source identifies where a message originated. -message Source { - // Site is the (optional) identity of the "site" that the source - // application is running within. - // - // The site is used to disambiguate between messages from different - // installations of the same application. - Identity site = 1; - - // Application is the identity of the Dogma application that produced the - // message. - Identity application = 2; - - // Handler is the identity of the Dogma handler that produced the message. - // - // It is the zero-value if the message was not produced by a handler. - Identity handler = 3; - - // InstanceId is the ID of the aggregate or process instance that produced - // the message. - // - // It is empty if the message was not produced by an aggregate or process - // handler. - string instance_id = 4 [features.field_presence = IMPLICIT]; -} - -// Message is the serialized representation of a [dogma.Message]. -message Message { - // TypeId is a unique identifier for the type of message, as per the Dogma - // message type registry. - UUID type_id = 1; - - // Description is a human-readable description of the message, as returned by - // the [dogma.Message.MessageDescription] method. - string description = 2 [features.field_presence = IMPLICIT]; - - // Data is the binary message data obtained by calling - // [dogma.Message.MarshalBinary] on the message. - bytes data = 3 [features.field_presence = IMPLICIT]; -} - -message Header { - // CausationId is the (optional) ID of the message that was the direct cause - // of the messages. - // - // If it is the zero-value, the messages were not caused by any other - // message. - UUID causation_id = 1; - - // CorrelationId is the (optional) ID of the first ancestor of the messages - // that was itself not caused by another message, that is, it's the root of - // the message chain that ultimately resulted in these messages. - // - // If it is the zero-value, the messages were not caused by any other - // message. - UUID correlation_id = 2; - - // Source identifies the origin of the messages. - Source source = 3; - - // Extensions is a set of extension values associated with the messages, - // their causal chain, or the envelope itself. - repeated google.protobuf.Any extensions = 4; - - // Baggage is a set of extension values that are propagated through the - // entire causal chain of messages. - repeated google.protobuf.Any baggage = 5; -} - -// Body contains the metadata and encoded form of a single message in an -// [Envelope] or [MultiEnvelope]. -message Body { - // MessageId is a unique identifier for the message in this envelope. - UUID message_id = 1; - - // IdempotencyKey is an application-defined value used to identify a command - // across retries. - // - // It is the zero-value if the message is not a command, or if the producer - // of the message did not provide an idempotency key. - string idempotency_key = 2 [features.field_presence = IMPLICIT]; - - // CreatedAt is the time at which the envelope was created. - // - // This is typically the point at which the message first enters the engine. - google.protobuf.Timestamp created_at = 3; - - // ScheduledFor is the time at which a deadline is reached. - // - // It is the zero-value if the message is a command or event. - google.protobuf.Timestamp scheduled_for = 4; - - // Message is the encoded representation of the [dogma.Message]. - Message message = 5; - - // Extensions is a set of extension values associated with this message. - // - // Any values in [Header.Extensions] are overridden by values in this field - // that have the same type URL. - repeated google.protobuf.Any extensions = 6; - - // Baggage is a set of extension values associated with this message and/or - // its causal chain. - // - // Any values in [Header.Baggage] are overridden by values in this field - // that have the same type URL. - repeated google.protobuf.Any baggage = 7; -} diff --git a/protobuf/envelopepb/envelope_primo.pb.go b/protobuf/envelopepb/envelope_primo.pb.go deleted file mode 100644 index c55d4d66..00000000 --- a/protobuf/envelopepb/envelope_primo.pb.go +++ /dev/null @@ -1,981 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/envelopepb/envelope.proto - -package envelopepb - -import ( - "fmt" - identitypb "github.com/dogmatiq/enginekit/protobuf/identitypb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - proto "google.golang.org/protobuf/proto" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" -) - -type EnvelopeBuilder struct { - prototype Envelope -} - -// NewEnvelopeBuilder returns a builder that constructs [Envelope] messages. -func NewEnvelopeBuilder() *EnvelopeBuilder { - return &EnvelopeBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *EnvelopeBuilder) From(x *Envelope) *EnvelopeBuilder { - proto.Reset(&b.prototype) - if x.HasHeader() { - b.prototype.SetHeader(x.GetHeader()) - } - if x.HasBody() { - b.prototype.SetBody(x.GetBody()) - } - return b -} - -// Build returns a new [Envelope] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *EnvelopeBuilder) Build() *Envelope { - m := &Envelope{} - if b.prototype.HasHeader() { - m.SetHeader(b.prototype.GetHeader()) - } - if b.prototype.HasBody() { - m.SetBody(b.prototype.GetBody()) - } - return m -} - -// WithHeader configures the builder to set the Header field to v, -// then returns b. -func (b *EnvelopeBuilder) WithHeader(v *Header) *EnvelopeBuilder { - b.prototype.SetHeader(v) - return b -} - -// WithBody configures the builder to set the Body field to v, -// then returns b. -func (b *EnvelopeBuilder) WithBody(v *Body) *EnvelopeBuilder { - b.prototype.SetBody(v) - return b -} - -type MultiEnvelopeBuilder struct { - prototype MultiEnvelope -} - -// NewMultiEnvelopeBuilder returns a builder that constructs [MultiEnvelope] messages. -func NewMultiEnvelopeBuilder() *MultiEnvelopeBuilder { - return &MultiEnvelopeBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *MultiEnvelopeBuilder) From(x *MultiEnvelope) *MultiEnvelopeBuilder { - proto.Reset(&b.prototype) - if x.HasHeader() { - b.prototype.SetHeader(x.GetHeader()) - } - b.prototype.SetBodies(x.GetBodies()) - return b -} - -// Build returns a new [MultiEnvelope] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *MultiEnvelopeBuilder) Build() *MultiEnvelope { - m := &MultiEnvelope{} - if b.prototype.HasHeader() { - m.SetHeader(b.prototype.GetHeader()) - } - m.SetBodies(b.prototype.GetBodies()) - return m -} - -// WithHeader configures the builder to set the Header field to v, -// then returns b. -func (b *MultiEnvelopeBuilder) WithHeader(v *Header) *MultiEnvelopeBuilder { - b.prototype.SetHeader(v) - return b -} - -// WithBodies configures the builder to set the Bodies field to v, -// then returns b. -func (b *MultiEnvelopeBuilder) WithBodies(v []*Body) *MultiEnvelopeBuilder { - b.prototype.SetBodies(v) - return b -} - -type SourceBuilder struct { - prototype Source -} - -// NewSourceBuilder returns a builder that constructs [Source] messages. -func NewSourceBuilder() *SourceBuilder { - return &SourceBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *SourceBuilder) From(x *Source) *SourceBuilder { - proto.Reset(&b.prototype) - if x.HasSite() { - b.prototype.SetSite(x.GetSite()) - } - if x.HasApplication() { - b.prototype.SetApplication(x.GetApplication()) - } - if x.HasHandler() { - b.prototype.SetHandler(x.GetHandler()) - } - b.prototype.SetInstanceId(x.GetInstanceId()) - return b -} - -// Build returns a new [Source] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *SourceBuilder) Build() *Source { - m := &Source{} - if b.prototype.HasSite() { - m.SetSite(b.prototype.GetSite()) - } - if b.prototype.HasApplication() { - m.SetApplication(b.prototype.GetApplication()) - } - if b.prototype.HasHandler() { - m.SetHandler(b.prototype.GetHandler()) - } - m.SetInstanceId(b.prototype.GetInstanceId()) - return m -} - -// WithSite configures the builder to set the Site field to v, -// then returns b. -func (b *SourceBuilder) WithSite(v *identitypb.Identity) *SourceBuilder { - b.prototype.SetSite(v) - return b -} - -// WithApplication configures the builder to set the Application field to v, -// then returns b. -func (b *SourceBuilder) WithApplication(v *identitypb.Identity) *SourceBuilder { - b.prototype.SetApplication(v) - return b -} - -// WithHandler configures the builder to set the Handler field to v, -// then returns b. -func (b *SourceBuilder) WithHandler(v *identitypb.Identity) *SourceBuilder { - b.prototype.SetHandler(v) - return b -} - -// WithInstanceId configures the builder to set the InstanceId field to v, -// then returns b. -func (b *SourceBuilder) WithInstanceId(v string) *SourceBuilder { - b.prototype.SetInstanceId(v) - return b -} - -type MessageBuilder struct { - prototype Message -} - -// NewMessageBuilder returns a builder that constructs [Message] messages. -func NewMessageBuilder() *MessageBuilder { - return &MessageBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *MessageBuilder) From(x *Message) *MessageBuilder { - proto.Reset(&b.prototype) - if x.HasTypeId() { - b.prototype.SetTypeId(x.GetTypeId()) - } - b.prototype.SetDescription(x.GetDescription()) - b.prototype.SetData(x.GetData()) - return b -} - -// Build returns a new [Message] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *MessageBuilder) Build() *Message { - m := &Message{} - if b.prototype.HasTypeId() { - m.SetTypeId(b.prototype.GetTypeId()) - } - m.SetDescription(b.prototype.GetDescription()) - m.SetData(b.prototype.GetData()) - return m -} - -// WithTypeId configures the builder to set the TypeId field to v, -// then returns b. -func (b *MessageBuilder) WithTypeId(v *uuidpb.UUID) *MessageBuilder { - b.prototype.SetTypeId(v) - return b -} - -// WithDescription configures the builder to set the Description field to v, -// then returns b. -func (b *MessageBuilder) WithDescription(v string) *MessageBuilder { - b.prototype.SetDescription(v) - return b -} - -// WithData configures the builder to set the Data field to v, -// then returns b. -func (b *MessageBuilder) WithData(v []byte) *MessageBuilder { - b.prototype.SetData(v) - return b -} - -type HeaderBuilder struct { - prototype Header -} - -// NewHeaderBuilder returns a builder that constructs [Header] messages. -func NewHeaderBuilder() *HeaderBuilder { - return &HeaderBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *HeaderBuilder) From(x *Header) *HeaderBuilder { - proto.Reset(&b.prototype) - if x.HasCausationId() { - b.prototype.SetCausationId(x.GetCausationId()) - } - if x.HasCorrelationId() { - b.prototype.SetCorrelationId(x.GetCorrelationId()) - } - if x.HasSource() { - b.prototype.SetSource(x.GetSource()) - } - b.prototype.SetExtensions(x.GetExtensions()) - b.prototype.SetBaggage(x.GetBaggage()) - return b -} - -// Build returns a new [Header] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *HeaderBuilder) Build() *Header { - m := &Header{} - if b.prototype.HasCausationId() { - m.SetCausationId(b.prototype.GetCausationId()) - } - if b.prototype.HasCorrelationId() { - m.SetCorrelationId(b.prototype.GetCorrelationId()) - } - if b.prototype.HasSource() { - m.SetSource(b.prototype.GetSource()) - } - m.SetExtensions(b.prototype.GetExtensions()) - m.SetBaggage(b.prototype.GetBaggage()) - return m -} - -// WithCausationId configures the builder to set the CausationId field to v, -// then returns b. -func (b *HeaderBuilder) WithCausationId(v *uuidpb.UUID) *HeaderBuilder { - b.prototype.SetCausationId(v) - return b -} - -// WithCorrelationId configures the builder to set the CorrelationId field to v, -// then returns b. -func (b *HeaderBuilder) WithCorrelationId(v *uuidpb.UUID) *HeaderBuilder { - b.prototype.SetCorrelationId(v) - return b -} - -// WithSource configures the builder to set the Source field to v, -// then returns b. -func (b *HeaderBuilder) WithSource(v *Source) *HeaderBuilder { - b.prototype.SetSource(v) - return b -} - -// WithExtensions configures the builder to set the Extensions field to v, -// then returns b. -func (b *HeaderBuilder) WithExtensions(v []*anypb.Any) *HeaderBuilder { - b.prototype.SetExtensions(v) - return b -} - -// WithBaggage configures the builder to set the Baggage field to v, -// then returns b. -func (b *HeaderBuilder) WithBaggage(v []*anypb.Any) *HeaderBuilder { - b.prototype.SetBaggage(v) - return b -} - -type BodyBuilder struct { - prototype Body -} - -// NewBodyBuilder returns a builder that constructs [Body] messages. -func NewBodyBuilder() *BodyBuilder { - return &BodyBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *BodyBuilder) From(x *Body) *BodyBuilder { - proto.Reset(&b.prototype) - if x.HasMessageId() { - b.prototype.SetMessageId(x.GetMessageId()) - } - b.prototype.SetIdempotencyKey(x.GetIdempotencyKey()) - if x.HasCreatedAt() { - b.prototype.SetCreatedAt(x.GetCreatedAt()) - } - if x.HasScheduledFor() { - b.prototype.SetScheduledFor(x.GetScheduledFor()) - } - if x.HasMessage() { - b.prototype.SetMessage(x.GetMessage()) - } - b.prototype.SetExtensions(x.GetExtensions()) - b.prototype.SetBaggage(x.GetBaggage()) - return b -} - -// Build returns a new [Body] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *BodyBuilder) Build() *Body { - m := &Body{} - if b.prototype.HasMessageId() { - m.SetMessageId(b.prototype.GetMessageId()) - } - m.SetIdempotencyKey(b.prototype.GetIdempotencyKey()) - if b.prototype.HasCreatedAt() { - m.SetCreatedAt(b.prototype.GetCreatedAt()) - } - if b.prototype.HasScheduledFor() { - m.SetScheduledFor(b.prototype.GetScheduledFor()) - } - if b.prototype.HasMessage() { - m.SetMessage(b.prototype.GetMessage()) - } - m.SetExtensions(b.prototype.GetExtensions()) - m.SetBaggage(b.prototype.GetBaggage()) - return m -} - -// WithMessageId configures the builder to set the MessageId field to v, -// then returns b. -func (b *BodyBuilder) WithMessageId(v *uuidpb.UUID) *BodyBuilder { - b.prototype.SetMessageId(v) - return b -} - -// WithIdempotencyKey configures the builder to set the IdempotencyKey field to v, -// then returns b. -func (b *BodyBuilder) WithIdempotencyKey(v string) *BodyBuilder { - b.prototype.SetIdempotencyKey(v) - return b -} - -// WithCreatedAt configures the builder to set the CreatedAt field to v, -// then returns b. -func (b *BodyBuilder) WithCreatedAt(v *timestamppb.Timestamp) *BodyBuilder { - b.prototype.SetCreatedAt(v) - return b -} - -// WithScheduledFor configures the builder to set the ScheduledFor field to v, -// then returns b. -func (b *BodyBuilder) WithScheduledFor(v *timestamppb.Timestamp) *BodyBuilder { - b.prototype.SetScheduledFor(v) - return b -} - -// WithMessage configures the builder to set the Message field to v, -// then returns b. -func (b *BodyBuilder) WithMessage(v *Message) *BodyBuilder { - b.prototype.SetMessage(v) - return b -} - -// WithExtensions configures the builder to set the Extensions field to v, -// then returns b. -func (b *BodyBuilder) WithExtensions(v []*anypb.Any) *BodyBuilder { - b.prototype.SetExtensions(v) - return b -} - -// WithBaggage configures the builder to set the Baggage field to v, -// then returns b. -func (b *BodyBuilder) WithBaggage(v []*anypb.Any) *BodyBuilder { - b.prototype.SetBaggage(v) - return b -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *Envelope) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = Envelope - type Envelope realType - fmt.Fprintf(f, format, (*Envelope)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *MultiEnvelope) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = MultiEnvelope - type MultiEnvelope realType - fmt.Fprintf(f, format, (*MultiEnvelope)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *Source) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = Source - type Source realType - fmt.Fprintf(f, format, (*Source)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *Message) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = Message - type Message realType - fmt.Fprintf(f, format, (*Message)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *Header) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = Header - type Header realType - fmt.Fprintf(f, format, (*Header)(x)) -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *Body) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = Body - type Body realType - fmt.Fprintf(f, format, (*Body)(x)) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*Envelope] to implement [encoding.BinaryMarshaler]. -func (x *Envelope) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*Envelope] to implement [encoding.BinaryUnmarshaler]. -func (x *Envelope) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*MultiEnvelope] to implement [encoding.BinaryMarshaler]. -func (x *MultiEnvelope) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*MultiEnvelope] to implement [encoding.BinaryUnmarshaler]. -func (x *MultiEnvelope) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*Source] to implement [encoding.BinaryMarshaler]. -func (x *Source) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*Source] to implement [encoding.BinaryUnmarshaler]. -func (x *Source) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*Message] to implement [encoding.BinaryMarshaler]. -func (x *Message) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*Message] to implement [encoding.BinaryUnmarshaler]. -func (x *Message) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*Header] to implement [encoding.BinaryMarshaler]. -func (x *Header) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*Header] to implement [encoding.BinaryUnmarshaler]. -func (x *Header) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*Body] to implement [encoding.BinaryMarshaler]. -func (x *Body) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*Body] to implement [encoding.BinaryUnmarshaler]. -func (x *Body) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/protobuf/envelopepb/envelope_test.go b/protobuf/envelopepb/envelope_test.go deleted file mode 100644 index fe015866..00000000 --- a/protobuf/envelopepb/envelope_test.go +++ /dev/null @@ -1,551 +0,0 @@ -package envelopepb_test - -import ( - "math" - "strings" - "testing" - - . "github.com/dogmatiq/enginekit/internal/test" - "github.com/dogmatiq/enginekit/protobuf/envelopepb" - . "github.com/dogmatiq/enginekit/protobuf/envelopepb" - identitypb "github.com/dogmatiq/enginekit/protobuf/identitypb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - "google.golang.org/protobuf/proto" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" -) - -func TestEnvelope_Validate(t *testing.T) { - t.Parallel() - - t.Run("when the envelope is valid", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *Envelope - }{ - { - "complete", - newEnvelope(), - }, - { - "without source site", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetSite(nil) - }), - }, - { - "without source handler", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetHandler(nil) - e.GetHeader().GetSource().SetInstanceId("") - e.GetBody().SetScheduledFor(nil) - }), - }, - { - "without source instance ID", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetInstanceId("") - e.GetBody().SetScheduledFor(nil) - }), - }, - { - "without extensions", - newEnvelope(func(e *Envelope) { - e.GetBody().SetExtensions(nil) - }), - }, - { - "with empty extension payload", - newEnvelope(func(e *Envelope) { - e.GetBody().SetExtensions([]*anypb.Any{{ - TypeUrl: "type.googleapis.com/example.Extension", - }}) - }), - }, - { - "with empty baggage payload", - newEnvelope(func(e *Envelope) { - e.GetBody().SetBaggage([]*anypb.Any{{ - TypeUrl: "type.googleapis.com/example.Baggage", - }}) - }), - }, - { - "without data", - newEnvelope(func(e *Envelope) { - e.GetBody().GetMessage().SetData(nil) - }), - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - if err := c.Subject.Validate(); err != nil { - t.Fatal(err) - } - }) - } - }) - - t.Run("when the envelope is invalid", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *Envelope - Expect string - }{ - { - "empty", - &Envelope{}, - "invalid header: must not be nil", - }, - { - "invalid message ID", - newEnvelope(func(e *Envelope) { - e.GetBody().SetMessageId(&uuidpb.UUID{}) - }), - "invalid body: invalid message ID (00000000-0000-0000-0000-000000000000): UUID must use version 4 or 5", - }, - { - "invalid causation ID", - newEnvelope(func(e *Envelope) { - e.GetHeader().SetCausationId(&uuidpb.UUID{}) - }), - "invalid header: invalid causation ID (00000000-0000-0000-0000-000000000000): UUID must use version 4 or 5", - }, - { - "invalid correlation ID", - newEnvelope(func(e *Envelope) { - e.GetHeader().SetCorrelationId(&uuidpb.UUID{}) - }), - "invalid header: invalid correlation ID (00000000-0000-0000-0000-000000000000): UUID must use version 4 or 5", - }, - { - "invalid source site", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetSite(&identitypb.Identity{}) - }), - "invalid header: invalid source: invalid site (00000000-0000-0000-0000-000000000000 ?): invalid name: must be between 1 and 255 bytes", - }, - { - "invalid source application", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetApplication(&identitypb.Identity{}) - }), - "invalid header: invalid source: invalid application (00000000-0000-0000-0000-000000000000 ?): invalid name: must be between 1 and 255 bytes", - }, - { - "invalid source handler", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetHandler(&identitypb.Identity{}) - }), - "invalid header: invalid source: invalid handler (00000000-0000-0000-0000-000000000000 ?): invalid name: must be between 1 and 255 bytes", - }, - { - "source instance ID without source handler", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetHandler(nil) - }), - "invalid header: invalid source: invalid instance ID: must not be specified without a handler", - }, - { - "scheduled-for time without source handler", - newEnvelope(func(e *Envelope) { - e.GetHeader().GetSource().SetHandler(nil) - e.GetHeader().GetSource().SetInstanceId("") - }), - "invalid body: invalid scheduled-for time: must not be specified without a source handler and instance ID", - }, - { - "invalid created-at time", - newEnvelope(func(e *Envelope) { - e.GetBody().SetCreatedAt(nil) - }), - "invalid body: invalid created-at time: proto: invalid nil Timestamp", - }, - { - "invalid scheduled-for time", - newEnvelope(func(e *Envelope) { - e.GetBody().SetScheduledFor(×tamppb.Timestamp{ - Seconds: math.MaxInt64, - Nanos: math.MaxInt32, - }) - }), - "invalid body: invalid scheduled-for time: proto: timestamp (seconds:9223372036854775807 nanos:2147483647) after 9999-12-31", - }, - { - "invalid description", - newEnvelope(func(e *Envelope) { - e.GetBody().GetMessage().SetDescription("") - }), - "invalid body: invalid message: invalid description: must not be empty", - }, - { - "empty header extension", - newEnvelope(func(e *Envelope) { - e.GetHeader().SetExtensions([]*anypb.Any{{}}) - }), - "invalid header: invalid extensions at index 0: type URL must not be empty", - }, - { - "empty header baggage", - newEnvelope(func(e *Envelope) { - e.GetHeader().SetBaggage([]*anypb.Any{nil}) - }), - "invalid header: invalid baggage at index 0: type URL must not be empty", - }, - { - "empty body extension", - newEnvelope(func(e *Envelope) { - e.GetBody().SetExtensions([]*anypb.Any{{}}) - }), - "invalid body: invalid extensions at index 0: type URL must not be empty", - }, - { - "empty body baggage", - newEnvelope(func(e *Envelope) { - e.GetBody().SetBaggage([]*anypb.Any{{}}) - }), - "invalid body: invalid baggage at index 0: type URL must not be empty", - }, - { - "without type ID", - newEnvelope(func(e *Envelope) { - e.GetBody().GetMessage().SetTypeId(nil) - }), - "invalid body: invalid message: invalid type ID (00000000-0000-0000-0000-000000000000): UUID must use version 4 or 5", - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - err := c.Subject.Validate() - if err == nil { - t.Fatal("expected an error") - } - - // defeat the protobuf's random injection of of whitespace into - // error messages. - actual := strings.ReplaceAll(err.Error(), "\u00a0", " ") - actual = strings.ReplaceAll(actual, " ", " ") - - if actual != c.Expect { - t.Fatalf("got %q, want %q", err, c.Expect) - } - }) - } - }) -} - -func TestEnvelope_AsMultiEnvelope(t *testing.T) { - t.Parallel() - - env := newEnvelope() - multi := env.AsMultiEnvelope() - - Expect(t, "unexpected header", multi.GetHeader(), env.GetHeader()) - - bodies := multi.GetBodies() - Expect(t, "unexpected body count", len(bodies), 1) - Expect(t, "unexpected body", bodies[0], env.GetBody()) -} - -func TestMultiEnvelope_All(t *testing.T) { - t.Parallel() - - t.Run("it yields each body as a standalone envelope", func(t *testing.T) { - t.Parallel() - - body1 := newEnvelope().GetBody() - body2 := newEnvelope().GetBody() - header := newEnvelope().GetHeader() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(header). - WithBodies([]*Body{body1, body2}). - Build() - - var got []*Envelope - for env := range multi.All() { - got = append(got, env) - } - - Expect(t, "unexpected envelope count", len(got), 2) - Expect(t, "unexpected envelope[0] header", got[0].GetHeader(), header) - Expect(t, "unexpected envelope[0] body", got[0].GetBody(), body1) - Expect(t, "unexpected envelope[1] header", got[1].GetHeader(), header) - Expect(t, "unexpected envelope[1] body", got[1].GetBody(), body2) - }) - - t.Run("it stops early when yield returns false", func(t *testing.T) { - t.Parallel() - - body1 := newEnvelope().GetBody() - body2 := newEnvelope().GetBody() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(newEnvelope().GetHeader()). - WithBodies([]*Body{body1, body2}). - Build() - - var got []*Envelope - for env := range multi.All() { - got = append(got, env) - break - } - - Expect(t, "unexpected envelope count", len(got), 1) - Expect(t, "unexpected envelope[0] body", got[0].GetBody(), body1) - }) - - t.Run("it yields nothing when there are no bodies", func(t *testing.T) { - t.Parallel() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(newEnvelope().GetHeader()). - Build() - - var got []*Envelope - for env := range multi.All() { - got = append(got, env) - } - - Expect(t, "unexpected envelope count", len(got), 0) - }) -} - -func TestMultiEnvelope_AppendBodies(t *testing.T) { - t.Parallel() - - t.Run("it appends bodies to the multi-envelope", func(t *testing.T) { - t.Parallel() - - body1 := newEnvelope().GetBody() - body2 := newEnvelope().GetBody() - body3 := newEnvelope().GetBody() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(newEnvelope().GetHeader()). - WithBodies([]*Body{body1}). - Build() - - multi.AppendBodies(body2, body3) - - got := multi.GetBodies() - Expect(t, "unexpected body count", len(got), 3) - Expect(t, "unexpected body[0]", got[0], body1) - Expect(t, "unexpected body[1]", got[1], body2) - Expect(t, "unexpected body[2]", got[2], body3) - }) - - t.Run("it appends to an empty multi-envelope", func(t *testing.T) { - t.Parallel() - - body := newEnvelope().GetBody() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(newEnvelope().GetHeader()). - Build() - - multi.AppendBodies(body) - - got := multi.GetBodies() - Expect(t, "unexpected body count", len(got), 1) - Expect(t, "unexpected body[0]", got[0], body) - }) -} - -func TestMultiEnvelope_TryAppendEnvelope(t *testing.T) { - t.Parallel() - - t.Run("it appends when headers are equivalent", func(t *testing.T) { - t.Parallel() - - header := newEnvelope().GetHeader() - body1 := newEnvelope().GetBody() - body2 := newEnvelope().GetBody() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(header). - WithBodies([]*Body{body1}). - Build() - - env := NewEnvelopeBuilder(). - WithHeader(header). - WithBody(body2). - Build() - - ok := multi.TryAppendEnvelope(env) - - Expect(t, "unexpected result", ok, true) - got := multi.GetBodies() - Expect(t, "unexpected body count", len(got), 2) - Expect(t, "unexpected body[0]", got[0], body1) - Expect(t, "unexpected body[1]", got[1], body2) - }) - - t.Run("it returns false when headers differ", func(t *testing.T) { - t.Parallel() - - body1 := newEnvelope().GetBody() - body2 := newEnvelope().GetBody() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(newEnvelope().GetHeader()). - WithBodies([]*Body{body1}). - Build() - - env := NewEnvelopeBuilder(). - WithHeader(newEnvelope().GetHeader()). - WithBody(body2). - Build() - - ok := multi.TryAppendEnvelope(env) - - Expect(t, "unexpected result", ok, false) - got := multi.GetBodies() - Expect(t, "unexpected body count", len(got), 1) - Expect(t, "unexpected body[0]", got[0], body1) - }) -} - -func TestWireCompatibility(t *testing.T) { - t.Parallel() - - env := newEnvelope(func(e *Envelope) { - e.GetHeader().SetExtensions([]*anypb.Any{ - {TypeUrl: "type.googleapis.com/example.ExtA", Value: []byte("header-a")}, - }) - e.GetHeader().SetBaggage([]*anypb.Any{ - {TypeUrl: "type.googleapis.com/example.BagA", Value: []byte("header-a")}, - }) - e.GetBody().SetExtensions([]*anypb.Any{ - {TypeUrl: "type.googleapis.com/example.ExtB", Value: []byte("body-b")}, - }) - e.GetBody().SetBaggage([]*anypb.Any{ - {TypeUrl: "type.googleapis.com/example.BagB", Value: []byte("body-b")}, - }) - }) - - t.Run("envelope unmarshals as multi-envelope", func(t *testing.T) { - t.Parallel() - - data, err := env.MarshalBinary() - if err != nil { - t.Fatal(err) - } - - var got MultiEnvelope - if err := got.UnmarshalBinary(data); err != nil { - t.Fatal(err) - } - - Expect(t, "unexpected header extensions", got.GetHeader().GetExtensions(), env.GetHeader().GetExtensions()) - Expect(t, "unexpected header baggage", got.GetHeader().GetBaggage(), env.GetHeader().GetBaggage()) - - if len(got.GetBodies()) != 1 { - t.Fatalf("unexpected body count: got %d, want 1", len(got.GetBodies())) - } - - Expect(t, "unexpected body extensions", got.GetBodies()[0].GetExtensions(), env.GetBody().GetExtensions()) - Expect(t, "unexpected body baggage", got.GetBodies()[0].GetBaggage(), env.GetBody().GetBaggage()) - }) - - t.Run("multi-envelope unmarshals as envelope", func(t *testing.T) { - t.Parallel() - - multi := NewMultiEnvelopeBuilder(). - WithHeader(env.GetHeader()). - WithBodies([]*Body{env.GetBody()}). - Build() - - data, err := multi.MarshalBinary() - if err != nil { - t.Fatal(err) - } - - var got Envelope - if err := got.UnmarshalBinary(data); err != nil { - t.Fatal(err) - } - - Expect(t, "unexpected header extensions", got.GetHeader().GetExtensions(), env.GetHeader().GetExtensions()) - Expect(t, "unexpected header baggage", got.GetHeader().GetBaggage(), env.GetHeader().GetBaggage()) - Expect(t, "unexpected body extensions", got.GetBody().GetExtensions(), env.GetBody().GetExtensions()) - Expect(t, "unexpected body baggage", got.GetBody().GetBaggage(), env.GetBody().GetBaggage()) - }) -} - -func newEnvelope(modifiers ...func(*Envelope)) *envelopepb.Envelope { - env := NewEnvelopeBuilder(). - WithHeader( - NewHeaderBuilder(). - WithCausationId(uuidpb.Generate()). - WithCorrelationId(uuidpb.Generate()). - WithSource(NewSourceBuilder(). - WithSite(identitypb.New("", uuidpb.Generate())). - WithApplication(identitypb.New("", uuidpb.Generate())). - WithHandler(identitypb.New("", uuidpb.Generate())). - WithInstanceId(""). - Build()). - Build(), - ). - WithBody( - NewBodyBuilder(). - WithMessageId(uuidpb.Generate()). - WithCreatedAt(timestamppb.Now()). - WithScheduledFor(timestamppb.Now()). - WithMessage(NewMessageBuilder(). - WithDescription(""). - WithTypeId(uuidpb.Generate()). - WithData([]byte("")). - Build(), - ). - WithExtensions([]*anypb.Any{ - { - TypeUrl: "type.googleapis.com/example.envelope.v1.Extension", - Value: []byte(""), - }, - }). - WithBaggage([]*anypb.Any{ - { - TypeUrl: "type.googleapis.com/example.envelope.v1.Baggage", - Value: []byte(""), - }, - }). - Build()). - Build() - - for _, fn := range modifiers { - fn(env) - } - - return env -} - -// newEmptyEnvelope returns an envelope with an empty header and body. -func newEmptyEnvelope() *Envelope { - return NewEnvelopeBuilder(). - WithHeader(NewHeaderBuilder().Build()). - WithBody(NewBodyBuilder().Build()). - Build() -} - -// mustMarshalAny returns m wrapped in an [anypb.Any]. -func mustMarshalAny(t testing.TB, m proto.Message) *anypb.Any { - t.Helper() - - a, err := anypb.New(m) - if err != nil { - t.Fatal(err) - } - - return a -} diff --git a/protobuf/envelopepb/extensions.go b/protobuf/envelopepb/extensions.go deleted file mode 100644 index 7a4d2a32..00000000 --- a/protobuf/envelopepb/extensions.go +++ /dev/null @@ -1,72 +0,0 @@ -package envelopepb - -import ( - "fmt" - - "google.golang.org/protobuf/proto" -) - -// SetExtension sets x as an extension on body. If an extension with the same -// type URL is already present, it is replaced. -// -// It panics if x is nil. -func SetExtension[ - T interface { - *E - proto.Message - }, - E any, -](body *Body, x T) { - if x == nil { - panic("value must not be nil") - } - - body.SetExtensions( - appendOrReplace( - body.GetExtensions(), - marshalAsAny(x), - ), - ) -} - -// GetExtension returns the extension matching T from env's extensions. -// -// Values in the envelope's body take precedence over those in its header. -// -// The second return value reports whether an extension of the matching type -// was present. The third return value is non-nil if the extension was present -// but could not be unmarshalled. -func GetExtension[ - T interface { - *E - proto.Message - }, - E any, -](env *Envelope) (T, bool, error) { - return findAnyValue[T]( - env.GetBody().GetExtensions(), - env.GetHeader().GetExtensions(), - ) -} - -// MustGetExtension returns the extension matching T from env's extensions. -// -// It panics if no extension of the matching type is present, or if it could not be -// unmarshalled. -func MustGetExtension[ - T interface { - *E - proto.Message - }, - E any, -](env *Envelope) T { - x, ok, err := GetExtension[T](env) - if err != nil { - panic(fmt.Sprintf("unable to unmarshal extension: %s", err)) - } - if !ok { - panic("extension is not present") - } - - return x -} diff --git a/protobuf/envelopepb/extensions.pb.go b/protobuf/envelopepb/extensions.pb.go deleted file mode 100644 index 13d8ddcc..00000000 --- a/protobuf/envelopepb/extensions.pb.go +++ /dev/null @@ -1,158 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.11 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/envelopepb/extensions.proto - -package envelopepb - -import ( - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// EventStreamPosition is an extension value for an [Envelope] that identifies -// the stream from which an event was obtained, and the offset of the event -// within that stream. -type EventStreamPosition struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_StreamId *uuidpb.UUID `protobuf:"bytes,1,opt,name=stream_id,json=streamId"` - xxx_hidden_Offset uint64 `protobuf:"varint,2,opt,name=offset"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EventStreamPosition) Reset() { - *x = EventStreamPosition{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EventStreamPosition) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EventStreamPosition) ProtoMessage() {} - -func (x *EventStreamPosition) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *EventStreamPosition) GetStreamId() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_StreamId - } - return nil -} - -func (x *EventStreamPosition) GetOffset() uint64 { - if x != nil { - return x.xxx_hidden_Offset - } - return 0 -} - -func (x *EventStreamPosition) SetStreamId(v *uuidpb.UUID) { - x.xxx_hidden_StreamId = v -} - -func (x *EventStreamPosition) SetOffset(v uint64) { - x.xxx_hidden_Offset = v -} - -func (x *EventStreamPosition) HasStreamId() bool { - if x == nil { - return false - } - return x.xxx_hidden_StreamId != nil -} - -func (x *EventStreamPosition) ClearStreamId() { - x.xxx_hidden_StreamId = nil -} - -type EventStreamPosition_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // StreamId is the identifier of the stream within which the event was - // recorded. - StreamId *uuidpb.UUID - // Offset is the position of the event within the stream. The first event is - // at offset zero. - Offset uint64 -} - -func (b0 EventStreamPosition_builder) Build() *EventStreamPosition { - m0 := &EventStreamPosition{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_StreamId = b.StreamId - x.xxx_hidden_Offset = b.Offset - return m0 -} - -var File_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_rawDesc = "" + - "\n" + - "Bgithub.com/dogmatiq/enginekit/protobuf/envelopepb/extensions.proto\x12\x0edogma.protobuf\x1a8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\"g\n" + - "\x13EventStreamPosition\x121\n" + - "\tstream_id\x18\x01 \x01(\v2\x14.dogma.protobuf.UUIDR\bstreamId\x12\x1d\n" + - "\x06offset\x18\x02 \x01(\x04B\x05\xaa\x01\x02\b\x02R\x06offsetB3Z1github.com/dogmatiq/enginekit/protobuf/envelopepbb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_goTypes = []any{ - (*EventStreamPosition)(nil), // 0: dogma.protobuf.EventStreamPosition - (*uuidpb.UUID)(nil), // 1: dogma.protobuf.UUID -} -var file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_depIdxs = []int32{ - 1, // 0: dogma.protobuf.EventStreamPosition.stream_id:type_name -> dogma.protobuf.UUID - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_init() } -func file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_init() { - if File_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_rawDesc)), - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto = out.File - file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_protobuf_envelopepb_extensions_proto_depIdxs = nil -} diff --git a/protobuf/envelopepb/extensions.proto b/protobuf/envelopepb/extensions.proto deleted file mode 100644 index 6ae71b3e..00000000 --- a/protobuf/envelopepb/extensions.proto +++ /dev/null @@ -1,19 +0,0 @@ -edition = "2024"; -package dogma.protobuf; - -option go_package = "github.com/dogmatiq/enginekit/protobuf/envelopepb"; - -import "github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto"; - -// EventStreamPosition is an extension value for an [Envelope] that identifies -// the stream from which an event was obtained, and the offset of the event -// within that stream. -message EventStreamPosition { - // StreamId is the identifier of the stream within which the event was - // recorded. - UUID stream_id = 1; - - // Offset is the position of the event within the stream. The first event is - // at offset zero. - uint64 offset = 2 [features.field_presence = IMPLICIT]; -} diff --git a/protobuf/envelopepb/extensions_primo.pb.go b/protobuf/envelopepb/extensions_primo.pb.go deleted file mode 100644 index 461c90d0..00000000 --- a/protobuf/envelopepb/extensions_primo.pb.go +++ /dev/null @@ -1,152 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/envelopepb/extensions.proto - -package envelopepb - -import ( - "fmt" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - proto "google.golang.org/protobuf/proto" -) - -type EventStreamPositionBuilder struct { - prototype EventStreamPosition -} - -// NewEventStreamPositionBuilder returns a builder that constructs [EventStreamPosition] messages. -func NewEventStreamPositionBuilder() *EventStreamPositionBuilder { - return &EventStreamPositionBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *EventStreamPositionBuilder) From(x *EventStreamPosition) *EventStreamPositionBuilder { - proto.Reset(&b.prototype) - if x.HasStreamId() { - b.prototype.SetStreamId(x.GetStreamId()) - } - b.prototype.SetOffset(x.GetOffset()) - return b -} - -// Build returns a new [EventStreamPosition] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *EventStreamPositionBuilder) Build() *EventStreamPosition { - m := &EventStreamPosition{} - if b.prototype.HasStreamId() { - m.SetStreamId(b.prototype.GetStreamId()) - } - m.SetOffset(b.prototype.GetOffset()) - return m -} - -// WithStreamId configures the builder to set the StreamId field to v, -// then returns b. -func (b *EventStreamPositionBuilder) WithStreamId(v *uuidpb.UUID) *EventStreamPositionBuilder { - b.prototype.SetStreamId(v) - return b -} - -// WithOffset configures the builder to set the Offset field to v, -// then returns b. -func (b *EventStreamPositionBuilder) WithOffset(v uint64) *EventStreamPositionBuilder { - b.prototype.SetOffset(v) - return b -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *EventStreamPosition) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = EventStreamPosition - type EventStreamPosition realType - fmt.Fprintf(f, format, (*EventStreamPosition)(x)) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*EventStreamPosition] to implement [encoding.BinaryMarshaler]. -func (x *EventStreamPosition) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*EventStreamPosition] to implement [encoding.BinaryUnmarshaler]. -func (x *EventStreamPosition) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/protobuf/envelopepb/extensions_test.go b/protobuf/envelopepb/extensions_test.go deleted file mode 100644 index 1d3b6a54..00000000 --- a/protobuf/envelopepb/extensions_test.go +++ /dev/null @@ -1,337 +0,0 @@ -package envelopepb_test - -import ( - "testing" - - . "github.com/dogmatiq/enginekit/internal/test" - . "github.com/dogmatiq/enginekit/protobuf/envelopepb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -func TestSetExtension(t *testing.T) { - t.Run("it adds the value to the body's extensions", func(t *testing.T) { - want, err := anypb.New(wrapperspb.String("hello")) - if err != nil { - t.Fatal(err) - } - - body := NewBodyBuilder().Build() - SetExtension(body, wrapperspb.String("hello")) - - Expect( - t, - "unexpected extensions", - body.GetExtensions(), - []*anypb.Any{want}, - ) - }) - - t.Run("when an extension with the same type URL is already present", func(t *testing.T) { - t.Run("it replaces the existing value", func(t *testing.T) { - want, err := anypb.New(wrapperspb.String("second")) - if err != nil { - t.Fatal(err) - } - - body := NewBodyBuilder().Build() - SetExtension(body, wrapperspb.String("first")) - SetExtension(body, wrapperspb.String("second")) - - Expect( - t, - "unexpected extensions", - body.GetExtensions(), - []*anypb.Any{want}, - ) - }) - }) - - t.Run("when extensions of other types are present", func(t *testing.T) { - t.Run("it appends the new value without disturbing the others", func(t *testing.T) { - wantInt, err := anypb.New(wrapperspb.Int64(42)) - if err != nil { - t.Fatal(err) - } - - wantString, err := anypb.New(wrapperspb.String("hello")) - if err != nil { - t.Fatal(err) - } - - body := NewBodyBuilder().Build() - SetExtension(body, wrapperspb.Int64(42)) - SetExtension(body, wrapperspb.String("hello")) - - Expect( - t, - "unexpected extensions", - body.GetExtensions(), - []*anypb.Any{wantInt, wantString}, - ) - }) - }) - - t.Run("when the value is nil", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - ExpectPanic( - t, - "value must not be nil", - func() { - SetExtension[*wrapperspb.StringValue](NewBodyBuilder().Build(), nil) - }, - ) - }) - }) -} - -func TestGetExtension(t *testing.T) { - t.Run("when a matching extension is present", func(t *testing.T) { - t.Run("it returns the value and true", func(t *testing.T) { - env := newEmptyEnvelope() - SetExtension(env.GetBody(), wrapperspb.String("hello")) - - got, ok, err := GetExtension[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find a matching extension") - } - - Expect( - t, - "unexpected extension value", - got, - wrapperspb.String("hello"), - ) - }) - }) - - t.Run("when a matching extension is present in the header", func(t *testing.T) { - t.Run("it returns the value and true", func(t *testing.T) { - env := newEmptyEnvelope() - env.GetHeader().SetExtensions([]*anypb.Any{ - mustMarshalAny(t, wrapperspb.String("hello")), - }) - - got, ok, err := GetExtension[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find a matching extension") - } - - Expect( - t, - "unexpected extension value", - got, - wrapperspb.String("hello"), - ) - }) - }) - - t.Run("when a matching extension is present in both the header and the body", func(t *testing.T) { - t.Run("it returns the value from the body", func(t *testing.T) { - env := newEmptyEnvelope() - env.GetHeader().SetExtensions([]*anypb.Any{ - mustMarshalAny(t, wrapperspb.String("header")), - }) - SetExtension(env.GetBody(), wrapperspb.String("body")) - - got, ok, err := GetExtension[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find a matching extension") - } - - Expect( - t, - "unexpected extension value", - got, - wrapperspb.String("body"), - ) - }) - }) - - t.Run("when the envelope was obtained from a multi-envelope", func(t *testing.T) { - t.Run("it returns values from the shared header", func(t *testing.T) { - multi := NewMultiEnvelopeBuilder(). - WithHeader(NewHeaderBuilder().Build()). - Build() - multi.GetHeader().SetExtensions([]*anypb.Any{ - mustMarshalAny(t, wrapperspb.String("shared")), - }) - multi.AppendBodies(NewBodyBuilder().Build()) - - for env := range multi.All() { - Expect( - t, - "unexpected extension value", - MustGetExtension[*wrapperspb.StringValue](env), - wrapperspb.String("shared"), - ) - } - }) - }) - - t.Run("when no extensions are present", func(t *testing.T) { - t.Run("it returns false", func(t *testing.T) { - env := newEmptyEnvelope() - - got, ok, err := GetExtension[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if ok { - t.Fatal("expected to find no matching extension") - } - if got != nil { - t.Fatalf("expected nil, got %v", got) - } - }) - }) - - t.Run("when only extensions of other types are present", func(t *testing.T) { - t.Run("it returns false", func(t *testing.T) { - env := newEmptyEnvelope() - SetExtension(env.GetBody(), wrapperspb.Int64(42)) - - got, ok, err := GetExtension[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if ok { - t.Fatal("expected to find no matching extension") - } - if got != nil { - t.Fatalf("expected nil, got %v", got) - } - }) - }) - - t.Run("when a value of the requested type has been set as baggage", func(t *testing.T) { - t.Run("it returns false (baggage and extensions are distinct)", func(t *testing.T) { - env := newEmptyEnvelope() - SetBaggage(env.GetBody(), wrapperspb.String("hello")) - - _, ok, err := GetExtension[*wrapperspb.StringValue](env) - if err != nil { - t.Fatal(err) - } - if ok { - t.Fatal("expected to find no matching extension") - } - }) - }) -} - -func TestMustGetExtension(t *testing.T) { - t.Run("when a matching extension is present", func(t *testing.T) { - t.Run("it returns the value", func(t *testing.T) { - env := newEmptyEnvelope() - SetExtension(env.GetBody(), wrapperspb.String("hello")) - - Expect( - t, - "unexpected extension value", - MustGetExtension[*wrapperspb.StringValue](env), - wrapperspb.String("hello"), - ) - }) - }) - - t.Run("when no extensions are present", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - ExpectPanic( - t, - "extension is not present", - func() { - MustGetExtension[*wrapperspb.StringValue](newEmptyEnvelope()) - }, - ) - }) - }) - - t.Run("when only extensions of other types are present", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - env := newEmptyEnvelope() - SetExtension(env.GetBody(), wrapperspb.Int64(42)) - - ExpectPanic( - t, - "extension is not present", - func() { - MustGetExtension[*wrapperspb.StringValue](env) - }, - ) - }) - }) - - t.Run("when the extension cannot be unmarshalled", func(t *testing.T) { - t.Run("it panics", func(t *testing.T) { - env := newEmptyEnvelope() - env.GetBody().SetExtensions([]*anypb.Any{ - { - TypeUrl: "type.googleapis.com/google.protobuf.StringValue", - Value: []byte{0x0a, 0x05}, // truncated string field - }, - }) - - defer func() { - if recover() == nil { - t.Fatal("expected a panic") - } - }() - - MustGetExtension[*wrapperspb.StringValue](env) - }) - }) -} - -func TestEventStreamPosition(t *testing.T) { - t.Run("when wrapped in anypb.Any", func(t *testing.T) { - t.Run("it has a stable, fully-qualified type URL", func(t *testing.T) { - a, err := anypb.New(&EventStreamPosition{}) - if err != nil { - t.Fatal(err) - } - - const want = "type.googleapis.com/dogma.protobuf.EventStreamPosition" - if a.GetTypeUrl() != want { - t.Fatalf("unexpected type URL:\n got: %s\nwant: %s", a.GetTypeUrl(), want) - } - }) - }) - - t.Run("when attached as an extension via SetExtension", func(t *testing.T) { - t.Run("it round-trips via GetExtension", func(t *testing.T) { - want := NewEventStreamPositionBuilder(). - WithStreamId(uuidpb.Generate()). - WithOffset(42). - Build() - - env := newEmptyEnvelope() - SetExtension(env.GetBody(), want) - - got, ok, err := GetExtension[*EventStreamPosition](env) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("expected to find an EventStreamPosition") - } - - Expect( - t, - "unexpected position", - got, - want, - ) - }) - }) -} diff --git a/protobuf/identitypb/doc.go b/protobuf/identitypb/doc.go deleted file mode 100644 index f1afb163..00000000 --- a/protobuf/identitypb/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package identitypb provides the "well-known" Identity type for representing -// application and handler (etc) identifies as Protocol Buffers messages. -package identitypb diff --git a/protobuf/identitypb/identity.go b/protobuf/identitypb/identity.go deleted file mode 100644 index 3ec68613..00000000 --- a/protobuf/identitypb/identity.go +++ /dev/null @@ -1,136 +0,0 @@ -package identitypb - -import ( - "errors" - "fmt" - "slices" - - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" -) - -// New returns a new identity with the given name and key. -func New(name string, key *uuidpb.UUID) *Identity { - x := NewIdentityBuilder(). - WithName(name). - WithKey(key). - Build() - - if err := x.Validate(); err != nil { - panic(x) - } - - return x -} - -// Parse returns a new identity with the given name and key by parsing the key -// as a UUID. -func Parse(name, key string) (*Identity, error) { - k, err := uuidpb.Parse(key) - if err != nil { - return nil, fmt.Errorf("invalid key: %w", err) - } - - x := NewIdentityBuilder(). - WithName(name). - WithKey(k). - Build() - - if err := x.Validate(); err != nil { - return nil, err - } - - return x, nil -} - -// MustParse returns a new identity with the given name and key by parsing the -// key as a UUID, or panics if unable to do so. -func MustParse(name, key string) *Identity { - x, err := Parse(name, key) - if err != nil { - panic(err) - } - - return x -} - -// Validate returns an error if x is invalid. -// -// It does not perform UTF-8 validation on the name. This should be validated by -// the engine when the identity is configured. -func (x *Identity) Validate() error { - name := x.GetName() - - if len(name) == 0 || len(name) > 255 { - return errors.New("invalid name: must be between 1 and 255 bytes") - } - - if err := x.GetKey().Validate(); err != nil { - return fmt.Errorf("invalid key: %w", err) - } - - return nil -} - -// MarshalText implements the [encoding.TextMarshaler] interface. -// -// The text representation is the UUID key followed by a space and the name, -// e.g. "5195fe85-eb3f-4121-84b0-be72cbc5722f handler-name". -func (x *Identity) MarshalText() ([]byte, error) { - if err := x.Validate(); err != nil { - return nil, err - } - - name := x.GetName() - text, _ := x.GetKey().MarshalText() - text = slices.Grow(text, 1+len(name)) - text = append(text, ' ') - text = append(text, name...) - - return text, nil -} - -// UnmarshalText implements the [encoding.TextUnmarshaler] interface. -func (x *Identity) UnmarshalText(text []byte) error { - if len(text) < 38 { - return errors.New("invalid identity format, expected UUID followed by a space and name") - } - - if text[36] != ' ' { - return errors.New("invalid identity format, expected space after UUID") - } - - var key uuidpb.UUID - if err := key.UnmarshalText(text[:36]); err != nil { - return fmt.Errorf("invalid key: %w", err) - } - - x.SetKey(&key) - x.SetName(string(text[37:])) - - return x.Validate() -} - -// AsString returns a human-readable representation of the identity. -func (x *Identity) AsString() string { - name := x.GetName() - if name == "" { - name = "?" - } - - return fmt.Sprintf("%s %s", x.GetKey(), name) - -} - -// GoString implements the [fmt.GoStringer] interface. -func (x *Identity) GoString() string { - return fmt.Sprintf( - "identitypb.New(%#v, %#v)", - x.GetName(), - x.GetKey(), - ) -} - -// Equal returns true if x and id are equal. -func (x *Identity) Equal(id *Identity) bool { - return x.GetName() == id.GetName() && x.GetKey().Equal(id.GetKey()) -} diff --git a/protobuf/identitypb/identity.pb.go b/protobuf/identitypb/identity.pb.go deleted file mode 100644 index 1725d631..00000000 --- a/protobuf/identitypb/identity.pb.go +++ /dev/null @@ -1,164 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.11 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/identitypb/identity.proto - -package identitypb - -import ( - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Identity represents the identity of an entity. -// -// It is used to identify Dogma applications, handlers, sites, streams, etc. -type Identity struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Name string `protobuf:"bytes,1,opt,name=name"` - xxx_hidden_Key *uuidpb.UUID `protobuf:"bytes,2,opt,name=key"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Identity) Reset() { - *x = Identity{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Identity) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Identity) ProtoMessage() {} - -func (x *Identity) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *Identity) GetName() string { - if x != nil { - return x.xxx_hidden_Name - } - return "" -} - -func (x *Identity) GetKey() *uuidpb.UUID { - if x != nil { - return x.xxx_hidden_Key - } - return nil -} - -func (x *Identity) SetName(v string) { - x.xxx_hidden_Name = v -} - -func (x *Identity) SetKey(v *uuidpb.UUID) { - x.xxx_hidden_Key = v -} - -func (x *Identity) HasKey() bool { - if x == nil { - return false - } - return x.xxx_hidden_Key != nil -} - -func (x *Identity) ClearKey() { - x.xxx_hidden_Key = nil -} - -type Identity_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - // Name is the entity's human-readable name. - // - // The name should be unique enough to allow a human to identify the entity - // without ambiguity. There is no hard requirement for uniqueness. - // - // Entity names may be changed at any time. - Name string - // Key is the entity's immutable, unique key. - // - // The key is used to uniquely identify the entity globally, and across all - // time. Every entity must have its own UUID, which must not be changed. - Key *uuidpb.UUID -} - -func (b0 Identity_builder) Build() *Identity { - m0 := &Identity{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_Name = b.Name - x.xxx_hidden_Key = b.Key - return m0 -} - -var File_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_rawDesc = "" + - "\n" + - "@github.com/dogmatiq/enginekit/protobuf/identitypb/identity.proto\x12\x0edogma.protobuf\x1a8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\"M\n" + - "\bIdentity\x12\x19\n" + - "\x04name\x18\x01 \x01(\tB\x05\xaa\x01\x02\b\x02R\x04name\x12&\n" + - "\x03key\x18\x02 \x01(\v2\x14.dogma.protobuf.UUIDR\x03keyB3Z1github.com/dogmatiq/enginekit/protobuf/identitypbb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_goTypes = []any{ - (*Identity)(nil), // 0: dogma.protobuf.Identity - (*uuidpb.UUID)(nil), // 1: dogma.protobuf.UUID -} -var file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_depIdxs = []int32{ - 1, // 0: dogma.protobuf.Identity.key:type_name -> dogma.protobuf.UUID - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_init() } -func file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_init() { - if File_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_rawDesc)), - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto = out.File - file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_protobuf_identitypb_identity_proto_depIdxs = nil -} diff --git a/protobuf/identitypb/identity.proto b/protobuf/identitypb/identity.proto deleted file mode 100644 index 6d7cde1c..00000000 --- a/protobuf/identitypb/identity.proto +++ /dev/null @@ -1,25 +0,0 @@ -edition = "2024"; -package dogma.protobuf; - -option go_package = "github.com/dogmatiq/enginekit/protobuf/identitypb"; - -import "github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto"; - -// Identity represents the identity of an entity. -// -// It is used to identify Dogma applications, handlers, sites, streams, etc. -message Identity { - // Name is the entity's human-readable name. - // - // The name should be unique enough to allow a human to identify the entity - // without ambiguity. There is no hard requirement for uniqueness. - // - // Entity names may be changed at any time. - string name = 1 [features.field_presence = IMPLICIT]; - - // Key is the entity's immutable, unique key. - // - // The key is used to uniquely identify the entity globally, and across all - // time. Every entity must have its own UUID, which must not be changed. - UUID key = 2; -} diff --git a/protobuf/identitypb/identity_primo.pb.go b/protobuf/identitypb/identity_primo.pb.go deleted file mode 100644 index 4008c4b3..00000000 --- a/protobuf/identitypb/identity_primo.pb.go +++ /dev/null @@ -1,152 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/identitypb/identity.proto - -package identitypb - -import ( - "fmt" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - proto "google.golang.org/protobuf/proto" -) - -type IdentityBuilder struct { - prototype Identity -} - -// NewIdentityBuilder returns a builder that constructs [Identity] messages. -func NewIdentityBuilder() *IdentityBuilder { - return &IdentityBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *IdentityBuilder) From(x *Identity) *IdentityBuilder { - proto.Reset(&b.prototype) - b.prototype.SetName(x.GetName()) - if x.HasKey() { - b.prototype.SetKey(x.GetKey()) - } - return b -} - -// Build returns a new [Identity] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *IdentityBuilder) Build() *Identity { - m := &Identity{} - m.SetName(b.prototype.GetName()) - if b.prototype.HasKey() { - m.SetKey(b.prototype.GetKey()) - } - return m -} - -// WithName configures the builder to set the Name field to v, -// then returns b. -func (b *IdentityBuilder) WithName(v string) *IdentityBuilder { - b.prototype.SetName(v) - return b -} - -// WithKey configures the builder to set the Key field to v, -// then returns b. -func (b *IdentityBuilder) WithKey(v *uuidpb.UUID) *IdentityBuilder { - b.prototype.SetKey(v) - return b -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *Identity) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = Identity - type Identity realType - fmt.Fprintf(f, format, (*Identity)(x)) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*Identity] to implement [encoding.BinaryMarshaler]. -func (x *Identity) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*Identity] to implement [encoding.BinaryUnmarshaler]. -func (x *Identity) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/protobuf/identitypb/identity_test.go b/protobuf/identitypb/identity_test.go deleted file mode 100644 index 43f09148..00000000 --- a/protobuf/identitypb/identity_test.go +++ /dev/null @@ -1,340 +0,0 @@ -package identitypb_test - -import ( - "strings" - "testing" - - "github.com/dogmatiq/enginekit/internal/test" - . "github.com/dogmatiq/enginekit/protobuf/identitypb" - uuidpb "github.com/dogmatiq/enginekit/protobuf/uuidpb" - proto "google.golang.org/protobuf/proto" -) - -func TestIdentity_Validate(t *testing.T) { - t.Parallel() - - t.Run("when the identity is valid", func(t *testing.T) { - t.Parallel() - - subject := New("", uuidpb.Generate()) - if err := subject.Validate(); err != nil { - t.Fatal(err) - } - }) - - t.Run("when the identity is invalid", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *Identity - Expect string - }{ - { - "too short", - NewIdentityBuilder(). - WithName(""). - WithKey(uuidpb.Generate()). - Build(), - "invalid name: must be between 1 and 255 bytes", - }, - { - "too long", - NewIdentityBuilder(). - WithName(strings.Repeat("*", 256)). - WithKey(uuidpb.Generate()). - Build(), - "invalid name: must be between 1 and 255 bytes", - }, - { - "invalid key", - NewIdentityBuilder(). - WithName(""). - WithKey(&uuidpb.UUID{}). - Build(), - "invalid key: UUID must use version 4 or 5", - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - err := c.Subject.Validate() - if err == nil { - t.Fatal("expected an error") - } - if err.Error() != c.Expect { - t.Fatalf("got %q, want %q", err, c.Expect) - } - }) - } - }) -} - -func TestIdentity_ParseAndMustParse(t *testing.T) { - t.Parallel() - - t.Run("when the identity is valid", func(t *testing.T) { - t.Run("Parse() returns the identity", func(t *testing.T) { - t.Parallel() - - actual, err := Parse( - "", - "a967a8b9-3f9c-4918-9a41-19577be5fec5", - ) - if err != nil { - t.Fatal(err) - } - - expect := NewIdentityBuilder(). - WithName(""). - WithKey(uuidpb. - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build()). - Build() - - if !actual.Equal(expect) { - t.Fatalf("unexpected identiy: got %s, want %s", actual, expect) - } - }) - - t.Run("MustParse() returns the identity", func(t *testing.T) { - t.Parallel() - - actual := MustParse( - "", - "a967a8b9-3f9c-4918-9a41-19577be5fec5", - ) - - expect := NewIdentityBuilder(). - WithName(""). - WithKey(uuidpb. - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build()). - Build() - - if !actual.Equal(expect) { - t.Fatalf("unexpected identiy: got %s, want %s", actual, expect) - } - }) - }) - - t.Run("when the identity is invalid", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Name string - Key string - Expect string - }{ - { - "too short", - "", - "a967a8b9-3f9c-4918-9a41-19577be5fec5", - "invalid name: must be between 1 and 255 bytes", - }, - { - "too long", - strings.Repeat("*", 256), - "a967a8b9-3f9c-4918-9a41-19577be5fec5", - "invalid name: must be between 1 and 255 bytes", - }, - { - "malformed key", - "", - "not-a-uuid", - "invalid key: invalid UUID format, expected 36 characters", - }, - { - "invalid key", - "", - "00000000-0000-0000-0000-000000000000", - "invalid key: UUID must use version 4 or 5", - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - t.Run("Parse() returns an error", func(t *testing.T) { - t.Parallel() - - _, err := Parse(c.Name, c.Key) - if err == nil { - t.Fatal("expected an error") - } - if err.Error() != c.Expect { - t.Fatalf("got %q, want %q", err, c.Expect) - } - }) - - t.Run("MustParse() panics", func(t *testing.T) { - t.Parallel() - - test.ExpectPanic( - t, - c.Expect, - func() { - MustParse(c.Name, c.Key) - }, - ) - }) - }) - } - }) -} - -func TestIdentity_MarshalText(t *testing.T) { - t.Parallel() - - t.Run("it produces the expected text", func(t *testing.T) { - t.Parallel() - - subject := New( - "", - uuidpb. - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build(), - ) - - text, err := subject.MarshalText() - if err != nil { - t.Fatal(err) - } - - want := "a967a8b9-3f9c-4918-9a41-19577be5fec5 " - if string(text) != want { - t.Fatalf("got %q, want %q", text, want) - } - }) - - t.Run("it returns an error for an invalid identity", func(t *testing.T) { - t.Parallel() - - subject := NewIdentityBuilder(). - WithName(""). - WithKey(uuidpb.Generate()). - Build() - - if _, err := subject.MarshalText(); err == nil { - t.Fatal("expected an error") - } - }) -} - -func TestIdentity_MarshalText_OnlyAllocatesTheResultAndUUIDText(t *testing.T) { - subject := New("", uuidpb.Generate()) - - allocs := testing.AllocsPerRun(100, func() { - subject.MarshalText() - }) - - if allocs != 2 { - t.Fatalf("expected 2 allocations, got %f", allocs) - } -} - -func TestIdentity_UnmarshalText(t *testing.T) { - t.Parallel() - - t.Run("it parses a valid identity", func(t *testing.T) { - t.Parallel() - - var subject Identity - err := subject.UnmarshalText([]byte("a967a8b9-3f9c-4918-9a41-19577be5fec5 ")) - if err != nil { - t.Fatal(err) - } - - expect := New( - "", - uuidpb. - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build(), - ) - - if !subject.Equal(expect) { - t.Fatalf("got %s, want %s", &subject, expect) - } - }) - - t.Run("it returns an error for invalid input", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Input string - }{ - {"too short", "abc"}, - {"missing space after UUID", "a967a8b9-3f9c-4918-9a41-19577be5fec5x"}, - {"malformed UUID", "not-a-valid-uuid-at-all-nope-nope!! "}, - {"empty name", "a967a8b9-3f9c-4918-9a41-19577be5fec5 "}, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - var subject Identity - if err := subject.UnmarshalText([]byte(c.Input)); err == nil { - t.Fatal("expected an error") - } - }) - } - }) -} - -func TestIdentity_UnmarshalText_OnlyAllocatesTheNameAndKey(t *testing.T) { - text := []byte("a967a8b9-3f9c-4918-9a41-19577be5fec5 ") - subject := New("", uuidpb.Generate()) - - allocs := testing.AllocsPerRun(100, func() { - subject.UnmarshalText(text) - }) - - if allocs != 2 { - t.Fatalf("expected 2 allocations, got %f", allocs) - } -} - -func TestIdentity_Equal(t *testing.T) { - t.Parallel() - - a := NewIdentityBuilder(). - WithName(""). - WithKey(uuidpb.Generate()). - Build() - - b1 := NewIdentityBuilder(). - WithName(""). - WithKey(uuidpb.Generate()). - Build() - - b2 := NewIdentityBuilder(). - WithName(b1.GetName()). - WithKey(proto.Clone(b1.GetKey()).(*uuidpb.UUID)). - Build() - - if !a.Equal(a) { - t.Fatal("expected a == a") - } - - if a.Equal(b1) { - t.Fatal("did not expect a == b1") - } - - if !b1.Equal(b2) { - t.Fatal("expected b1 == b2") - } -} diff --git a/protobuf/uuidpb/doc.go b/protobuf/uuidpb/doc.go deleted file mode 100644 index ab9c7392..00000000 --- a/protobuf/uuidpb/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package uuidpb provides the "well-known" UUID type for representing RFC 9562 -// (and formerly RFC 4122) UUIDs as Protocol Buffers messages. -package uuidpb diff --git a/protobuf/uuidpb/uuid.go b/protobuf/uuidpb/uuid.go deleted file mode 100644 index e8a71f5a..00000000 --- a/protobuf/uuidpb/uuid.go +++ /dev/null @@ -1,503 +0,0 @@ -package uuidpb - -import ( - "crypto/rand" - "crypto/sha1" - "errors" - "fmt" -) - -// Generate returns a new randomly generated (v4) UUID. -func Generate() *UUID { - var data [16]byte - if _, err := rand.Read(data[:]); err != nil { - panic(err) - } - - data[6] = (data[6] & 0x0f) | 0x40 // Version 4 - data[8] = (data[8] & 0x3f) | 0x80 // Variant is 10 (RFC 9562) - - return FromByteArray(data) -} - -// Derive returns a new SHA-1 derived (v5) UUID from the given namespace and -// names. -func Derive[T ~string | ~[]byte](ns *UUID, names ...T) *UUID { - hash := sha1.New() - var data [20]byte // storage for derived UUID and intermediate hash - - CopyBytes(ns, data[:16]) - - for _, name := range names { - hash.Reset() - hash.Write(data[:16]) - hash.Write([]byte(name)) - hash.Sum(data[:0]) - - data[6] = (data[6] & 0x0f) | 0x50 // Version 5 - data[8] = (data[8] & 0x3f) | 0x80 // Variant is 10 (RFC 9562) - } - - return NewUUIDBuilder(). - WithUpper( - uint64(data[0])<<56 | - uint64(data[1])<<48 | - uint64(data[2])<<40 | - uint64(data[3])<<32 | - uint64(data[4])<<24 | - uint64(data[5])<<16 | - uint64(data[6])<<8 | - uint64(data[7]), - ). - WithLower( - uint64(data[8])<<56 | - uint64(data[9])<<48 | - uint64(data[10])<<40 | - uint64(data[11])<<32 | - uint64(data[12])<<24 | - uint64(data[13])<<16 | - uint64(data[14])<<8 | - uint64(data[15]), - ). - Build() -} - -// Parse parses an RFC 9562 "hex-and-dash" UUID string. -func Parse(str string) (*UUID, error) { - uuid := &UUID{} - if err := uuid.UnmarshalText([]byte(str)); err != nil { - return nil, err - } - return uuid, nil -} - -// MustParse parses an RFC 9562 "hex-and-dash" UUID string, or panics if unable -// to do so. -func MustParse(str string) *UUID { - uuid, err := Parse(str) - if err != nil { - panic(err) - } - return uuid -} - -// ParseAsByteArray parses an RFC 9562 "hex-and-dash" UUID string directly to -// its byte array representation. -// -// This is equivalent to calling AsByteArray() on the result of Parse(str), -// but avoids all allocations. -func ParseAsByteArray(str string) ([16]byte, error) { - var uuid [16]byte - return uuid, ParseIntoBytes(str, uuid[:]) -} - -// MustParseAsByteArray parses an RFC 9562 "hex-and-dash" UUID string directly -// to its byte array representation, or panics if unable to do so. -// -// This is equivalent to calling MustParse(str).AsByteArray(), but avoids -// all allocations. -func MustParseAsByteArray(str string) [16]byte { - uuid, err := ParseAsByteArray(str) - if err != nil { - panic(err) - } - return uuid -} - -// ParseIntoBytes parses an RFC 9562 "hex-and-dash" UUID string into the given -// byte slice. -// -// This is equivalent to calling [CopyBytes] on the result of [Parse], but -// avoids all allocations. -func ParseIntoBytes(str string, dst []byte) error { - if len(dst) < 16 { - return fmt.Errorf( - "destination slice must have at least 16 bytes, got %d", - len(dst), - ) - } - - if len(str) != 36 { - return errors.New("invalid UUID format, expected 36 characters") - } - - read := 0 - write := 0 - - for read < 36 { - switch read { - case 8, 13, 18, 23: - if str[read] != '-' { - return fmt.Errorf("invalid UUID format, expected hyphen at position %d", read) - } - - read++ - } - - high, err := fromHex(str, read) - if err != nil { - return err - } - - read++ - - low, err := fromHex(str, read) - if err != nil { - return err - } - - read++ - - dst[write] = (high << 4) | low - write++ - } - - return nil -} - -// MustParseIntoBytes parses an RFC 9562 "hex-and-dash" UUID string into the -// given byte slice, or panics if unable to do so. -// -// This is equivalent to calling [CopyBytes] on the result of [MustParse], but -// avoids all allocations. -func MustParseIntoBytes(str string, dst []byte) { - if err := ParseIntoBytes(str, dst); err != nil { - panic(err) - } -} - -// ParseAsBytes parses an RFC 9562 "hex-and-dash" UUID string directly to its -// byte slice representation. -// -// This is equivalent to calling AsBytes() on the result of Parse(str), -// but avoids allocation of the intermediate [UUID] struct. -func ParseAsBytes(str string) ([]byte, error) { - uuid, err := ParseAsByteArray(str) - if err != nil { - return nil, err - } - return uuid[:], nil -} - -// MustParseAsBytes parses an RFC 9562 "hex-and-dash" UUID string directly to -// its byte slice representation, or panics if unable to do so. -// -// This is equivalent to calling MustParse(str).AsBytes(), but avoids allocation -// of the intermediate [UUID] struct. -func MustParseAsBytes(str string) []byte { - uuid := MustParseAsByteArray(str) - return uuid[:] -} - -// FromBytes returns a UUID from a byte slice. -// -// It returns an error if the length of the slice is not exactly 16 bytes. -func FromBytes[T ~[]B, B byte](data T) (*UUID, error) { - if len(data) != 16 { - return nil, fmt.Errorf("slice must be exactly 16 bytes, got %d", len(data)) - } - - return NewUUIDBuilder(). - WithUpper( - uint64(data[0])<<56 | - uint64(data[1])<<48 | - uint64(data[2])<<40 | - uint64(data[3])<<32 | - uint64(data[4])<<24 | - uint64(data[5])<<16 | - uint64(data[6])<<8 | - uint64(data[7]), - ). - WithLower( - uint64(data[8])<<56 | - uint64(data[9])<<48 | - uint64(data[10])<<40 | - uint64(data[11])<<32 | - uint64(data[12])<<24 | - uint64(data[13])<<16 | - uint64(data[14])<<8 | - uint64(data[15]), - ). - Build(), nil -} - -// FromByteArray returns a UUID from a byte array. -func FromByteArray[T ~[16]B, B byte](data T) *UUID { - return NewUUIDBuilder(). - WithUpper( - uint64(data[0])<<56 | - uint64(data[1])<<48 | - uint64(data[2])<<40 | - uint64(data[3])<<32 | - uint64(data[4])<<24 | - uint64(data[5])<<16 | - uint64(data[6])<<8 | - uint64(data[7]), - ). - WithLower( - uint64(data[8])<<56 | - uint64(data[9])<<48 | - uint64(data[10])<<40 | - uint64(data[11])<<32 | - uint64(data[12])<<24 | - uint64(data[13])<<16 | - uint64(data[14])<<8 | - uint64(data[15]), - ). - Build() -} - -// AsByteArray returns the UUID as a byte array. -func AsByteArray[T ~[16]B, B ~byte](x *UUID) T { - var data T - - if x != nil { - upper := x.GetUpper() - lower := x.GetLower() - - data[0] = B(upper >> 56) - data[1] = B(upper >> 48) - data[2] = B(upper >> 40) - data[3] = B(upper >> 32) - data[4] = B(upper >> 24) - data[5] = B(upper >> 16) - data[6] = B(upper >> 8) - data[7] = B(upper) - - data[8] = B(lower >> 56) - data[9] = B(lower >> 48) - data[10] = B(lower >> 40) - data[11] = B(lower >> 32) - data[12] = B(lower >> 24) - data[13] = B(lower >> 16) - data[14] = B(lower >> 8) - data[15] = B(lower) - } - - return data -} - -// CopyBytes copies the binary representation of x into dst. -// -// It returns the number of elements copied, which will be the minimum of 16 and -// len(dst). -func CopyBytes[T ~[]B, B byte](x *UUID, dst T) int { - data := AsByteArray[[16]B](x) - return copy(dst, data[:]) -} - -// AsBytes returns the UUID as a byte slice. -func (x *UUID) AsBytes() []byte { - data := AsByteArray[[16]byte](x) - return data[:] -} - -// AsByteArray returns the UUID as a byte array. -func (x *UUID) AsByteArray() [16]byte { - return AsByteArray[[16]byte](x) -} - -// AsString returns the UUID as an RFC 9562 string. -func (x *UUID) AsString() string { - data := asHex(x.GetUpper(), x.GetLower()) - return string(data[:]) -} - -// GoString implements the [fmt.GoStringer] interface. -func (x *UUID) GoString() string { - return fmt.Sprintf("uuidpb.MustParse(%q)", x.AsString()) -} - -// DapperString implements [github.com/dogmatiq/dapper.Stringer]. -func (x *UUID) DapperString() string { - return x.AsString() -} - -// MarshalText implements the [encoding.TextMarshaler] interface. -func (x *UUID) MarshalText() ([]byte, error) { - data := asHex(x.GetUpper(), x.GetLower()) - return data[:], nil -} - -// UnmarshalText implements the [encoding.TextUnmarshaler] interface. -func (x *UUID) UnmarshalText(text []byte) error { - if len(text) != 36 { - return errors.New("invalid UUID format, expected 36 characters") - } - - x.xxx_hidden_Upper = 0 - x.xxx_hidden_Lower = 0 - - var ( - target = &x.xxx_hidden_Upper - shift = 60 - ) - - for index, digit := range text { - switch index { - case 18: - target = &x.xxx_hidden_Lower - shift = 60 - fallthrough - case 8, 13, 23: - if digit != '-' { - return fmt.Errorf("invalid UUID format, expected hyphen at position %d", index) - } - default: - value := fromHexMap[digit] - if value == bad { - return fmt.Errorf("invalid UUID format, expected hex digit at position %d", index) - } - - *target |= uint64(value) << shift - shift -= 4 - } - } - - return nil -} - -// Validate returns an error if x is not a valid Version 4 (random) or Version 5 -// (name-based) UUID. -func (x *UUID) Validate() error { - // Only versions 4 (random) and 5 (name-based/SHA-1) are accepted. - // - // Version 7 (time-ordered) is intentionally excluded: - // - Its primary benefit — B-tree index locality — only applies when the - // UUID is a clustered primary key in a non-sharded B-tree database at - // high write volumes. Dogmatiq uses UUIDs for message IDs and handler - // identities, neither of which fits this profile. - // - In sharded or distributed databases (CockroachDB, Spanner, Cassandra, - // etc.), the sequential timestamp prefix causes write hotspots, actively - // harming throughput. - // - The naive implementation does not guarantee monotonicity within a - // millisecond; true per-millisecond ordering requires shared mutable - // state and clock-rollback handling. - // - The embedded timestamp permanently leaks creation time to any observer - // of the identifier, which is undesirable for security-sensitive uses. - switch (x.GetUpper() >> 8) & 0xf0 { - case 0x40, 0x50: - default: - return errors.New("UUID must use version 4 or 5") - } - - if variant := (x.GetLower() >> 56) & 0xc0; variant != 0x80 { - return fmt.Errorf("UUID must use RFC 9562 variant") - } - - return nil -} - -// Equal returns true if x and id are equal. -func (x *UUID) Equal(id *UUID) bool { - return x.GetUpper() == id.GetUpper() && x.GetLower() == id.GetLower() -} - -// Less returns true if x is less than id. -func (x *UUID) Less(id *UUID) bool { - return x.Compare(id) < 0 -} - -// Compare performs a three-way comparison between x and id. -func (x *UUID) Compare(id *UUID) int { - return compare( - x.GetUpper(), - x.GetLower(), - id.GetUpper(), - id.GetLower(), - ) -} - -// bad is a sentinel value that indicates an invalid hexadecimal digit. -const bad = 255 - -var ( - toHex = [16]byte{ - '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f', - } - - fromHexMap = [256]byte{ - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, bad, bad, bad, bad, bad, bad, - bad, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, bad, - } -) - -// fromHex returns the numerical value of a hexadecimal digit at the given index -// in str. -func fromHex(str string, index int) (byte, error) { - v := fromHexMap[str[index]] - if v == bad { - return 0, fmt.Errorf("invalid UUID format, expected hex digit at position %d", index) - } - return v, nil -} - -// plain is a [comparable] representation of a [UUID]. -type plain struct { - upper, lower uint64 -} - -// DapperString implements [github.com/dogmatiq/dapper.Stringer]. -func (k plain) DapperString() string { - data := asHex(k.upper, k.lower) - return string(data[:]) -} - -// asHex returns the RFC 9562 "hex-and-dash" representation of a UUID with -// the given upper and lower components. -func asHex(upper, lower uint64) [36]byte { - var str [36]byte - - source := &upper - shift := 60 - - for index := range 36 { - switch index { - case 18: - source = &lower - shift = 60 - fallthrough - case 8, 13, 23: - str[index] = '-' - default: - value := (*source >> shift) & 0xf - str[index] = toHex[value] - shift -= 4 - } - } - - return str -} - -func compare( - upperA, lowerA uint64, - upperB, lowerB uint64, -) int { - if upperA > upperB { - return 1 - } else if upperA < upperB { - return -1 - } else if lowerA > lowerB { - return 1 - } else if lowerA < lowerB { - return -1 - } - return 0 -} diff --git a/protobuf/uuidpb/uuid.pb.go b/protobuf/uuidpb/uuid.pb.go deleted file mode 100644 index c68aef3a..00000000 --- a/protobuf/uuidpb/uuid.pb.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.11 -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto - -package uuidpb - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// UUID is a size-optimized representation of an RFC 9562 UUID. -type UUID struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_Upper uint64 `protobuf:"varint,1,opt,name=upper"` - xxx_hidden_Lower uint64 `protobuf:"varint,2,opt,name=lower"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *UUID) Reset() { - *x = UUID{} - mi := &file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *UUID) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UUID) ProtoMessage() {} - -func (x *UUID) ProtoReflect() protoreflect.Message { - mi := &file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *UUID) GetUpper() uint64 { - if x != nil { - return x.xxx_hidden_Upper - } - return 0 -} - -func (x *UUID) GetLower() uint64 { - if x != nil { - return x.xxx_hidden_Lower - } - return 0 -} - -func (x *UUID) SetUpper(v uint64) { - x.xxx_hidden_Upper = v -} - -func (x *UUID) SetLower(v uint64) { - x.xxx_hidden_Lower = v -} - -type UUID_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - Upper uint64 - Lower uint64 -} - -func (b0 UUID_builder) Build() *UUID { - m0 := &UUID{} - b, x := &b0, m0 - _, _ = b, x - x.xxx_hidden_Upper = b.Upper - x.xxx_hidden_Lower = b.Lower - return m0 -} - -var File_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto protoreflect.FileDescriptor - -const file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_rawDesc = "" + - "\n" + - "8github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto\x12\x0edogma.protobuf\"@\n" + - "\x04UUID\x12\x1b\n" + - "\x05upper\x18\x01 \x01(\x04B\x05\xaa\x01\x02\b\x02R\x05upper\x12\x1b\n" + - "\x05lower\x18\x02 \x01(\x04B\x05\xaa\x01\x02\b\x02R\x05lowerB/Z-github.com/dogmatiq/enginekit/protobuf/uuidpbb\beditionsp\xe9\a" - -var file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_goTypes = []any{ - (*UUID)(nil), // 0: dogma.protobuf.UUID -} -var file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_init() } -func file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_init() { - if File_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_rawDesc), len(file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_rawDesc)), - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_goTypes, - DependencyIndexes: file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_depIdxs, - MessageInfos: file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_msgTypes, - }.Build() - File_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto = out.File - file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_goTypes = nil - file_github_com_dogmatiq_enginekit_protobuf_uuidpb_uuid_proto_depIdxs = nil -} diff --git a/protobuf/uuidpb/uuid.proto b/protobuf/uuidpb/uuid.proto deleted file mode 100644 index 3ad5de9a..00000000 --- a/protobuf/uuidpb/uuid.proto +++ /dev/null @@ -1,10 +0,0 @@ -edition = "2024"; -package dogma.protobuf; - -option go_package = "github.com/dogmatiq/enginekit/protobuf/uuidpb"; - -// UUID is a size-optimized representation of an RFC 9562 UUID. -message UUID { - uint64 upper = 1 [features.field_presence = IMPLICIT]; - uint64 lower = 2 [features.field_presence = IMPLICIT]; -} diff --git a/protobuf/uuidpb/uuid_primo.pb.go b/protobuf/uuidpb/uuid_primo.pb.go deleted file mode 100644 index c13b9124..00000000 --- a/protobuf/uuidpb/uuid_primo.pb.go +++ /dev/null @@ -1,147 +0,0 @@ -// Code generated by protoc-gen-go-primo. DO NOT EDIT. -// versions: -// protoc-gen-go-primo v -// protoc v6.33.1 -// source: github.com/dogmatiq/enginekit/protobuf/uuidpb/uuid.proto - -package uuidpb - -import ( - "fmt" - proto "google.golang.org/protobuf/proto" -) - -type UUIDBuilder struct { - prototype UUID -} - -// NewUUIDBuilder returns a builder that constructs [UUID] messages. -func NewUUIDBuilder() *UUIDBuilder { - return &UUIDBuilder{} -} - -// From configures the builder to use x as the prototype for new messages, -// then returns b. -// -// It performs a shallow copy of x, such that any changes made via the builder -// do not modify x. It does not make a copy of the field values themselves. -func (b *UUIDBuilder) From(x *UUID) *UUIDBuilder { - proto.Reset(&b.prototype) - b.prototype.SetUpper(x.GetUpper()) - b.prototype.SetLower(x.GetLower()) - return b -} - -// Build returns a new [UUID] containing the values configured via the builder. -// -// Each call returns a new message, such that future changes to the builder do -// not modify previously constructed messages. -func (b *UUIDBuilder) Build() *UUID { - m := &UUID{} - m.SetUpper(b.prototype.GetUpper()) - m.SetLower(b.prototype.GetLower()) - return m -} - -// WithUpper configures the builder to set the Upper field to v, -// then returns b. -func (b *UUIDBuilder) WithUpper(v uint64) *UUIDBuilder { - b.prototype.SetUpper(v) - return b -} - -// WithLower configures the builder to set the Lower field to v, -// then returns b. -func (b *UUIDBuilder) WithLower(v uint64) *UUIDBuilder { - b.prototype.SetLower(v) - return b -} - -// Format formats x according to the given [fmt] verb. -// -// It implements [fmt.Formatter], taking precedence over the String() method -// generated by the Protocol Buffers compiler. -// -// For the %s and %q verbs it uses the string returned by x.AsString() if x -// provides such a method. For the %#v verb it uses the string returned by -// x.GoString() if x provides such a method. Otherwise it formats x as though this -// method were not defined. -// -// AsString() and GoString() are called even when x is nil, since some message -// types handle a nil receiver themselves. If either method panics, the panic is -// formatted the same way the fmt package formats a panicking String() method. -func (x *UUID) Format(f fmt.State, verb rune) { - format := fmt.FormatString(f, verb) - - if verb == 's' || verb == 'q' { - if s, ok := any(x).(interface { - AsString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=AsString method: %v)", verb, r) - } - }() - return s.AsString(), true - }() - if ok { - fmt.Fprintf(f, format, result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } - - if verb == 'v' && f.Flag('#') { - if s, ok := any(x).(interface { - GoString() string - }); ok { - result, ok := func() (result string, ok bool) { - defer func() { - if r := recover(); r != nil { - result = fmt.Sprintf("%%!%c(PANIC=GoString method: %v)", verb, r) - } - }() - return s.GoString(), true - }() - if ok { - fmt.Fprintf(f, fmt.FormatString(f, 's'), result) - } else if x == nil { - fmt.Fprint(f, "") - } else { - fmt.Fprint(f, result) - } - return - } - } else { - switch verb { - case 'v', 's', 'x', 'X', 'q': - fmt.Fprintf(f, format, x.String()) - return - } - } - - type realType = UUID - type UUID realType - fmt.Fprintf(f, format, (*UUID)(x)) -} - -// MarshalBinary returns the binary representation of the message, equivalent to -// calling proto.Marshal(x). -// -// It allows [*UUID] to implement [encoding.BinaryMarshaler]. -func (x *UUID) MarshalBinary() ([]byte, error) { - return proto.Marshal(x) -} - -// UnmarshalBinary populates x from its binary representation, equivalent to -// calling proto.Unmarshal(data, x). -// -// It allows [*UUID] to implement [encoding.BinaryUnmarshaler]. -func (x *UUID) UnmarshalBinary(data []byte) error { - return proto.Unmarshal(data, x) -} diff --git a/protobuf/uuidpb/uuid_test.go b/protobuf/uuidpb/uuid_test.go deleted file mode 100644 index 0c98807d..00000000 --- a/protobuf/uuidpb/uuid_test.go +++ /dev/null @@ -1,954 +0,0 @@ -package uuidpb_test - -import ( - "bytes" - "testing" - - "github.com/dogmatiq/dapper" - . "github.com/dogmatiq/enginekit/protobuf/uuidpb" - "google.golang.org/protobuf/proto" -) - -func TestGenerate(t *testing.T) { - t.Parallel() - - uuid := Generate() - - if err := uuid.Validate(); err != nil { - t.Fatal(err) - } -} - -func TestDerive(t *testing.T) { - t.Parallel() - - t.Run("it derives a UUID from the namespace using SHA-1 and string name", func(t *testing.T) { - t.Parallel() - - ns := MustParse("9236932a-4971-43d0-a667-26711872681e") - const want = "bf6d549f-7fa3-52ea-a9cd-2817080dd532" - got := Derive(ns, "") - - if got.AsString() != want { - t.Fatalf("unexpected derived UUID: got %q, want %q", got, want) - } - }) - - t.Run("it derives a UUID from the namespace using SHA-1 and byte-slice name", func(t *testing.T) { - t.Parallel() - - ns := MustParse("9236932a-4971-43d0-a667-26711872681e") - const want = "bf6d549f-7fa3-52ea-a9cd-2817080dd532" - got := Derive(ns, []byte("")) - - if got.AsString() != want { - t.Fatalf("unexpected derived UUID: got %q, want %q", got, want) - } - }) - - t.Run("it performs multiple derivations when passed multiple names", func(t *testing.T) { - t.Parallel() - - ns := Generate() - intermediate := Derive(ns, "") - want := Derive(intermediate, "") - got := Derive(ns, "", "") - - if !got.Equal(want) { - t.Fatalf("unexpected derived UUID: got %q, want %q", got, want) - } - }) -} - -var ( - validCases = []struct { - Desc string - String string - }{ - {"lowercase", "a967a8b9-3f9c-4918-9a41-19577be5fec5"}, - {"uppercase", "A967A8B9-3F9C-4918-9A41-19577BE5FEC5"}, - } - - invalidCases = []struct { - Desc string - String string - }{ - {"empty string", ""}, - {"too short", "3493af5d-e4d0-4f3b-a73d-048e6b08496"}, - {"too long", "3493af5d-e4d0-4f3b-a73d-048e6b08496ab"}, - {"no hyphens", "a967a8b93f9c49189a4119577be5fec5"}, - {"no hyphens at position 8", "7e770248_7336-4cee-881d-f24013e6c1bf"}, - {"no hyphens at position 13", "7e770248-7336_4cee-881d-f24013e6c1bf"}, - {"no hyphens at position 18", "7e770248-7336-4cee_881d-f24013e6c1bf"}, - {"no hyphens at position 23", "7e770248-7336-4cee-881d_f24013e6c1bf"}, - {"non-hex character", "26c4a622-e4b4-4Xe7-8454-e3dc90f7d1d8"}, - } -) - -func TestParse(t *testing.T) { - t.Parallel() - - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range validCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - expect := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - actual, err := Parse(c.String) - if err != nil { - t.Fatal(err) - } - - if !proto.Equal(actual, expect) { - t.Fatalf("got %q, want %q", actual, expect) - } - }) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range invalidCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - _, err := Parse(c.String) - if err == nil { - t.Fatal("expected an error") - } - }) - } - }) -} - -func BenchmarkParse(b *testing.B) { - for b.Loop() { - _, err := Parse("a967a8b9-3f9c-4918-9a41-19577be5fec5") - if err != nil { - b.Fatal(err) - } - } -} - -func TestParse_OnlyAllocatesTheUUID(t *testing.T) { - allocs := testing.AllocsPerRun(100, func() { - Parse("a967a8b9-3f9c-4918-9a41-19577be5fec5") - }) - - if allocs != 1 { - t.Fatalf("expected exactly 1 allocation, got %f", allocs) - } -} - -func TestMustParse(t *testing.T) { - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - expect := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - actual := MustParse("a967a8b9-3f9c-4918-9a41-19577be5fec5") - - if !proto.Equal(actual, expect) { - t.Fatalf("got %q, want %q", actual, expect) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - defer func() { - if r := recover(); r == nil { - t.Fatal("expected a panic") - } - }() - - MustParse("invalid") - }) -} - -func TestParseAsByteArray(t *testing.T) { - t.Parallel() - - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range validCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - expect := [16]byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - actual, err := ParseAsByteArray(c.String) - if err != nil { - t.Fatal(err) - } - - if actual != expect { - t.Fatalf("got %v, want %v", actual, expect) - } - }) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range invalidCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - _, err := ParseAsByteArray(c.String) - if err == nil { - t.Fatal("expected an error") - } - }) - } - }) -} - -func TestParseAsByteArray_DoesNotAlloc(t *testing.T) { - allocs := testing.AllocsPerRun(100, func() { - ParseAsByteArray("a967a8b9-3f9c-4918-9a41-19577be5fec5") - }) - - if allocs != 0 { - t.Fatalf("expected zero allocations, got %f", allocs) - } -} - -func BenchmarkParseAsByteArray(b *testing.B) { - for b.Loop() { - _, err := ParseAsByteArray("a967a8b9-3f9c-4918-9a41-19577be5fec5") - if err != nil { - b.Fatal(err) - } - } -} - -func TestMustParseAsByteArray(t *testing.T) { - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - expect := [16]byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - actual := MustParseAsByteArray("a967a8b9-3f9c-4918-9a41-19577be5fec5") - - if actual != expect { - t.Fatalf("got %q, want %q", actual, expect) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - defer func() { - if r := recover(); r == nil { - t.Fatal("expected a panic") - } - }() - - MustParseAsByteArray("invalid") - }) -} - -func TestParseIntoBytes(t *testing.T) { - t.Parallel() - - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range validCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - expect := [16]byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - var actual [16]byte - err := ParseIntoBytes(c.String, actual[:]) - if err != nil { - t.Fatal(err) - } - - if actual != expect { - t.Fatalf("got %v, want %v", actual, expect) - } - }) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range invalidCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - var target [16]byte - err := ParseIntoBytes(c.String, target[:]) - if err == nil { - t.Fatal("expected an error") - } - }) - } - }) - - t.Run("when the target slice does not have adequate length", func(t *testing.T) { - t.Parallel() - - var target [8]byte - err := ParseIntoBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5", target[:]) - if err == nil { - t.Fatal("expected an error") - } - }) -} - -func TestParseIntoBytes_DoesNotAlloc(t *testing.T) { - allocs := testing.AllocsPerRun(100, func() { - var target [16]byte - ParseIntoBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5", target[:]) - }) - - if allocs != 0 { - t.Fatalf("expected zero allocations, got %f", allocs) - } -} - -func BenchmarkParseIntoBytes(b *testing.B) { - var target [16]byte - - for b.Loop() { - err := ParseIntoBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5", target[:]) - if err != nil { - b.Fatal(err) - } - } -} - -func TestMustParseIntoBytes(t *testing.T) { - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - expect := [16]byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - var actual [16]byte - MustParseIntoBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5", actual[:]) - - if actual != expect { - t.Fatalf("got %q, want %q", actual, expect) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - defer func() { - if r := recover(); r == nil { - t.Fatal("expected a panic") - } - }() - - var target [16]byte - MustParseIntoBytes("invalid", target[:]) - }) - - t.Run("when the target slice does not have adequate length", func(t *testing.T) { - t.Parallel() - - defer func() { - if r := recover(); r == nil { - t.Fatal("expected a panic") - } - }() - - var target [8]byte - MustParseIntoBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5", target[:]) - }) -} - -func TestParseAsBytes(t *testing.T) { - t.Parallel() - - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range validCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - expect := []byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - actual, err := ParseAsBytes(c.String) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(actual, expect) { - t.Fatalf("got %v, want %v", actual, expect) - } - }) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - for _, c := range invalidCases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - _, err := ParseAsBytes(c.String) - if err == nil { - t.Fatal("expected an error") - } - }) - } - }) -} - -func BenchmarkParseAsBytes(b *testing.B) { - for b.Loop() { - _, err := ParseAsBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5") - if err != nil { - b.Fatal(err) - } - } -} - -func TestMustParseAsBytes(t *testing.T) { - t.Run("when the string is a valid UUID", func(t *testing.T) { - t.Parallel() - - expect := []byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - actual := MustParseAsBytes("a967a8b9-3f9c-4918-9a41-19577be5fec5") - - if !bytes.Equal(actual, expect) { - t.Fatalf("got %q, want %q", actual, expect) - } - }) - - t.Run("when the string is not a valid UUID", func(t *testing.T) { - t.Parallel() - - defer func() { - if r := recover(); r == nil { - t.Fatal("expected a panic") - } - }() - - MustParseAsBytes("invalid") - }) -} - -func TestFromBytes(t *testing.T) { - t.Parallel() - - subject := []byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - - actual, err := FromBytes(subject) - if err != nil { - t.Fatal(err) - } - - expect := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - if !proto.Equal(actual, expect) { - t.Fatalf("got %s, want %s", actual, expect) - } - - _, err = FromBytes(subject[:8]) - if err == nil { - t.Fatal("expected an error") - } -} - -func TestFromByteArray(t *testing.T) { - t.Parallel() - - subject := [16]byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - - actual := FromByteArray(subject) - expect := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - if !proto.Equal(actual, expect) { - t.Fatalf("got %s, want %s", actual, expect) - } -} - -func TestAsByteArray(t *testing.T) { - t.Parallel() - - subject := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - actual := AsByteArray[[16]byte](subject) - expect := [16]byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - - if actual != expect { - t.Fatalf("got %#v, want %#v", actual, expect) - } -} - -func TestCopyBytes(t *testing.T) { - t.Parallel() - - subject := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - t.Run("fills the target slice with the UUID's bytes", func(t *testing.T) { - var actual [16]byte - n := CopyBytes(subject, actual[:]) - expect := []byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - } - - if !bytes.Equal(actual[:], expect) { - t.Fatalf("got %q, want %q", actual, expect) - } - - if n != 16 { - t.Fatalf("got %d, want 16", n) - } - }) - - t.Run("it truncates to the target slice's length", func(t *testing.T) { - var actual [8]byte - n := CopyBytes(subject, actual[:]) - expect := []byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - } - - if !bytes.Equal(actual[:], expect) { - t.Fatalf("got %q, want %q", actual, expect) - } - - if n != 8 { - t.Fatalf("got %d, want 8", n) - } - }) -} - -func TestUUID_AsBytesAndAsByteArray(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *UUID - Expect []byte - }{ - { - "nil", - nil, - []byte{ - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }, - }, - { - "zero", - &UUID{}, - []byte{ - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }, - }, - { - "non-zero", - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build(), - []byte{ - 0xa9, 0x67, 0xa8, 0xb9, - 0x3f, 0x9c, 0x49, 0x18, - 0x9a, 0x41, 0x19, 0x57, - 0x7b, 0xe5, 0xfe, 0xc5, - }, - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - actual := c.Subject.AsBytes() - - if !bytes.Equal(actual, c.Expect) { - t.Fatalf("got %q, want %q", actual, c.Expect) - } - - array := c.Subject.AsByteArray() - if !bytes.Equal(array[:], c.Expect) { - t.Fatalf("got %q, want %q", array, c.Expect) - } - }) - } -} - -func TestUUID_AsString(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *UUID - Expect string - }{ - {"nil", nil, "00000000-0000-0000-0000-000000000000"}, - {"zero", &UUID{}, "00000000-0000-0000-0000-000000000000"}, - { - "non-zero", - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build(), - "a967a8b9-3f9c-4918-9a41-19577be5fec5", - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - actual := c.Subject.AsString() - - if actual != c.Expect { - t.Fatalf("got %q, want %q", actual, c.Expect) - } - }) - } -} - -func TestUUID_MarshalText(t *testing.T) { - t.Parallel() - - subject := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - text, err := subject.MarshalText() - if err != nil { - t.Fatal(err) - } - - if got, want := string(text), "a967a8b9-3f9c-4918-9a41-19577be5fec5"; got != want { - t.Fatalf("got %q, want %q", got, want) - } -} - -func TestUUID_UnmarshalText(t *testing.T) { - t.Parallel() - - t.Run("it populates the UUID from text", func(t *testing.T) { - t.Parallel() - - var subject UUID - if err := subject.UnmarshalText([]byte("a967a8b9-3f9c-4918-9a41-19577be5fec5")); err != nil { - t.Fatal(err) - } - - if got, want := subject.GetUpper(), uint64(0xa967a8b93f9c4918); got != want { - t.Fatalf("upper: got %#x, want %#x", got, want) - } - if got, want := subject.GetLower(), uint64(0x9a4119577be5fec5); got != want { - t.Fatalf("lower: got %#x, want %#x", got, want) - } - }) - - t.Run("it returns an error for invalid text", func(t *testing.T) { - t.Parallel() - - var subject UUID - if err := subject.UnmarshalText([]byte("not-a-uuid")); err == nil { - t.Fatal("expected an error") - } - }) -} - -func TestUUID_UnmarshalText_DoesNotAlloc(t *testing.T) { - text := []byte("a967a8b9-3f9c-4918-9a41-19577be5fec5") - var subject UUID - - allocs := testing.AllocsPerRun(100, func() { - subject.UnmarshalText(text) - }) - - if allocs != 0 { - t.Fatalf("expected zero allocations, got %f", allocs) - } -} - -func TestUUID_DapperString(t *testing.T) { - t.Parallel() - - subject := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - actual := dapper.Format(subject) - expect := "*github.com/dogmatiq/enginekit/protobuf/uuidpb.UUID [a967a8b9-3f9c-4918-9a41-19577be5fec5]" - - if actual != expect { - t.Fatalf("got %q, want %q", actual, expect) - } -} - -func TestUUID_Validate(t *testing.T) { - t.Parallel() - - t.Run("when the UUID is valid", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *UUID - }{ - { - "version 4", - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build(), - }, - { - "version 5", - NewUUIDBuilder(). - WithUpper(0xbf6d549f7fa352ea). - WithLower(0xa9cd2817080dd532). - Build(), - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - if err := c.Subject.Validate(); err != nil { - t.Fatal(err) - } - }) - } - }) - - t.Run("when the UUID is invalid", func(t *testing.T) { - t.Parallel() - - cases := []struct { - Desc string - Subject *UUID - Expect string - }{ - { - "nil UUID", - &UUID{}, - "UUID must use version 4 or 5", - }, - { - "omni UUID", - NewUUIDBuilder(). - WithUpper(0xffffffffffffffff). - WithLower(0xffffffffffffffff). - Build(), - "UUID must use version 4 or 5", - }, - { - "wrong version", - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c_f0_18). - WithLower(0x9a4119577be5fec5). - Build(), - "UUID must use version 4 or 5", - }, - { - "wrong variant", - NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0xc0_4119577be5fec5). - Build(), - "UUID must use RFC 9562 variant", - }, - } - - for _, c := range cases { - t.Run(c.Desc, func(t *testing.T) { - t.Parallel() - - err := c.Subject.Validate() - if err == nil { - t.Fatal("expected an error") - } - if err.Error() != c.Expect { - t.Fatalf("got %q, want %q", err, c.Expect) - } - }) - } - }) -} - -func TestUUID_Equal(t *testing.T) { - t.Parallel() - - a := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - b := NewUUIDBuilder(). - WithUpper(0x3f9c4918a967a8b9). - WithLower(0x7be5fec59a411957). - Build() - - if a.Equal(b) { - t.Fatal("did not expect a == b") - } - - if !a.Equal(a) { - t.Fatal("did not expect a != b") - } -} - -func TestUUID_Less(t *testing.T) { - t.Parallel() - - a := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - b := NewUUIDBuilder(). - WithUpper(0x3f9c4918a967a8b9). - WithLower(0x7be5fec59a411957). - Build() - - if a.Less(b) { - t.Fatal("did not expect a < b") - } - - if !b.Less(a) { - t.Fatal("did not expect b >= a") - } - - if a.Less(a) { - t.Fatal("did not expect a < b") - } -} - -func TestUUID_Compare(t *testing.T) { - t.Parallel() - - t.Run("compares both the upper and lower parts", func(t *testing.T) { - a := NewUUIDBuilder(). - WithUpper(0xa967a8b93f9c4918). - WithLower(0x9a4119577be5fec5). - Build() - - b := NewUUIDBuilder(). - WithUpper(0x3f9c4918a967a8b9). - WithLower(0x7be5fec59a411957). - Build() - - c := NewUUIDBuilder(). - WithUpper(0x3f9c4918a967a8b9). - WithLower(0x0000fec59a411957). - Build() - - if a.Compare(b) < 0 { - t.Fatal("did not expect a < b") - } - - if b.Compare(a) >= 0 { - t.Fatal("did not expect b >= a") - } - - if a.Compare(a) != 0 { - t.Fatal("did not expect a != b") - } - - if b.Compare(c) <= 0 { - t.Fatal("did not expect b <= c") - } - }) - - t.Run("subtraction overflow regression", func(t *testing.T) { - a, err := Parse("e6929f89-acb1-4994-8248-d097ad20da5f") - if err != nil { - t.Fatal(err) - } - - b, err := Parse("46471d80-5b50-44a0-a8a8-261941336291") - if err != nil { - t.Fatal(err) - } - - if a.Compare(b) <= 0 { - t.Fatal("did not expect a <= b") - } - }) -} diff --git a/telemetry/attribute.go b/telemetry/attribute.go index 5e484855..bd927296 100644 --- a/telemetry/attribute.go +++ b/telemetry/attribute.go @@ -8,7 +8,7 @@ import ( "time" "github.com/dogmatiq/dogma" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/uuidpb" "go.opentelemetry.io/otel/attribute" "golang.org/x/exp/constraints" ) diff --git a/uuidcollection/doc.go b/uuidcollection/doc.go new file mode 100644 index 00000000..97f2f362 --- /dev/null +++ b/uuidcollection/doc.go @@ -0,0 +1,2 @@ +// Package uuidcollection provides collections keyed by UUID. +package uuidcollection diff --git a/protobuf/uuidpb/map.go b/uuidcollection/map.go similarity index 76% rename from protobuf/uuidpb/map.go rename to uuidcollection/map.go index b14bbf87..0961099b 100644 --- a/protobuf/uuidpb/map.go +++ b/uuidcollection/map.go @@ -1,17 +1,19 @@ -package uuidpb +package uuidcollection import ( "iter" "maps" + + "github.com/dogmatiq/protobuf/uuidpb" ) -// Map is a map from [UUID] to values of type T. +// Map is a map from [uuidpb.UUID] to values of type T. type Map[T any] struct { m map[key]T } // Get returns the value associated with the given key. -func (m *Map[T]) Get(k *UUID) (T, bool) { +func (m *Map[T]) Get(k *uuidpb.UUID) (T, bool) { if m.Len() == 0 { var zero T return zero, false @@ -22,7 +24,7 @@ func (m *Map[T]) Get(k *UUID) (T, bool) { } // Has reports whether the map contains a value for the given key. -func (m *Map[T]) Has(k *UUID) bool { +func (m *Map[T]) Has(k *uuidpb.UUID) bool { if m.Len() == 0 { return false } @@ -32,7 +34,7 @@ func (m *Map[T]) Has(k *UUID) bool { } // Set sets the value associated with the given key. -func (m *Map[T]) Set(k *UUID, v T) { +func (m *Map[T]) Set(k *uuidpb.UUID, v T) { if m.m == nil { m.m = map[key]T{} } @@ -41,15 +43,15 @@ func (m *Map[T]) Set(k *UUID, v T) { } // Delete removes the value associated with the given key. -func (m *Map[T]) Delete(k *UUID) { +func (m *Map[T]) Delete(k *uuidpb.UUID) { if m.Len() != 0 { delete(m.m, asKey(k)) } } // All yields all key/value pairs in the map. -func (m *Map[T]) All() iter.Seq2[*UUID, T] { - return func(yield func(*UUID, T) bool) { +func (m *Map[T]) All() iter.Seq2[*uuidpb.UUID, T] { + return func(yield func(*uuidpb.UUID, T) bool) { if m != nil { for k, v := range m.m { if !yield(k.asUUID(), v) { @@ -61,8 +63,8 @@ func (m *Map[T]) All() iter.Seq2[*UUID, T] { } // Keys yields all keys in the map. -func (m *Map[T]) Keys() iter.Seq[*UUID] { - return func(yield func(*UUID) bool) { +func (m *Map[T]) Keys() iter.Seq[*uuidpb.UUID] { + return func(yield func(*uuidpb.UUID) bool) { if m != nil { for k := range m.m { if !yield(k.asUUID()) { @@ -122,13 +124,13 @@ func (m *Map[T]) Clone() *Map[T] { type key struct{ upper, lower uint64 } // asKey converts a UUID to a key. -func asKey(u *UUID) key { +func asKey(u *uuidpb.UUID) key { return key{u.GetUpper(), u.GetLower()} } // asUUID converts a key back to a UUID. -func (k key) asUUID() *UUID { - return NewUUIDBuilder(). +func (k key) asUUID() *uuidpb.UUID { + return uuidpb.NewUUIDBuilder(). WithUpper(k.upper). WithLower(k.lower). Build() diff --git a/protobuf/uuidpb/map_test.go b/uuidcollection/map_test.go similarity index 97% rename from protobuf/uuidpb/map_test.go rename to uuidcollection/map_test.go index 7658afbf..3de6cb23 100644 --- a/protobuf/uuidpb/map_test.go +++ b/uuidcollection/map_test.go @@ -1,13 +1,13 @@ -package uuidpb_test +package uuidcollection_test import ( "maps" "slices" "testing" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" - . "github.com/dogmatiq/enginekit/protobuf/uuidpb" + . "github.com/dogmatiq/enginekit/uuidcollection" "github.com/dogmatiq/enginekit/x/xrapid" + "github.com/dogmatiq/protobuf/uuidpb" "pgregory.net/rapid" ) diff --git a/protobuf/uuidpb/set.go b/uuidcollection/set.go similarity index 79% rename from protobuf/uuidpb/set.go rename to uuidcollection/set.go index 885ce0c5..8985d43e 100644 --- a/protobuf/uuidpb/set.go +++ b/uuidcollection/set.go @@ -1,19 +1,21 @@ -package uuidpb +package uuidcollection import ( "iter" "maps" "slices" "strings" + + "github.com/dogmatiq/protobuf/uuidpb" ) -// Set is a collection of [UUID] values. +// Set is a collection of [uuidpb.UUID] values. type Set struct { m map[key]struct{} } -// NewSet creates a new set containing the given [UUID] values. -func NewSet(values ...*UUID) *Set { +// NewSet creates a new set containing the given [uuidpb.UUID] values. +func NewSet(values ...*uuidpb.UUID) *Set { s := &Set{ m: make(map[key]struct{}, len(values)), } @@ -25,8 +27,8 @@ func NewSet(values ...*UUID) *Set { return s } -// Has reports whether the set contains the given [UUID]. -func (s *Set) Has(v *UUID) bool { +// Has reports whether the set contains the given [uuidpb.UUID]. +func (s *Set) Has(v *uuidpb.UUID) bool { return s.has(asKey(v)) } @@ -39,8 +41,8 @@ func (s *Set) has(k key) bool { return ok } -// Add adds the given [UUID] to the set. -func (s *Set) Add(v *UUID) { +// Add adds the given [uuidpb.UUID] to the set. +func (s *Set) Add(v *uuidpb.UUID) { s.add(asKey(v)) } @@ -52,16 +54,16 @@ func (s *Set) add(k key) { s.m[k] = struct{}{} } -// Delete removes the given [UUID] from the set. -func (s *Set) Delete(v *UUID) { +// Delete removes the given [uuidpb.UUID] from the set. +func (s *Set) Delete(v *uuidpb.UUID) { if s != nil { delete(s.m, asKey(v)) } } // All yields all members of the set. -func (s *Set) All() iter.Seq[*UUID] { - return func(yield func(*UUID) bool) { +func (s *Set) All() iter.Seq[*uuidpb.UUID] { + return func(yield func(*uuidpb.UUID) bool) { if s != nil { for v := range s.m { if !yield(v.asUUID()) { @@ -167,7 +169,7 @@ func (s *Set) String() string { sorted := slices.SortedFunc( s.All(), - (*UUID).Compare, + (*uuidpb.UUID).Compare, ) for i, v := range sorted { @@ -190,16 +192,16 @@ func (s *Set) DapperString() string { // GoString returns a Go-syntax representation of the set. func (s *Set) GoString() string { if s == nil { - return "(*uuidpb.Set)(nil)" + return "(*uuidcollection.Set)(nil)" } var w strings.Builder - w.WriteString("uuidpb.NewSet(") + w.WriteString("uuidcollection.NewSet(") sorted := slices.SortedFunc( s.All(), - (*UUID).Compare, + (*uuidpb.UUID).Compare, ) for i, v := range sorted { diff --git a/protobuf/uuidpb/set_test.go b/uuidcollection/set_test.go similarity index 87% rename from protobuf/uuidpb/set_test.go rename to uuidcollection/set_test.go index 63a45a99..e1109946 100644 --- a/protobuf/uuidpb/set_test.go +++ b/uuidcollection/set_test.go @@ -1,13 +1,13 @@ -package uuidpb_test +package uuidcollection_test import ( "maps" "slices" "testing" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" - . "github.com/dogmatiq/enginekit/protobuf/uuidpb" + . "github.com/dogmatiq/enginekit/uuidcollection" "github.com/dogmatiq/enginekit/x/xrapid" + "github.com/dogmatiq/protobuf/uuidpb" "pgregory.net/rapid" ) @@ -52,12 +52,12 @@ func TestSet(t *testing.T) { }, "diff with intersecting set": func(t *rapid.T) { v := xrapid.SampledFromSeq(maps.Keys(expected)).Draw(t, "existing member") - other := uuidpb.NewSet(uuidpb.MustParse(v)) + other := NewSet(uuidpb.MustParse(v)) subject = subject.Diff(other) delete(expected, v) }, "diff with disjoint set": func(t *rapid.T) { - other := uuidpb.NewSet(uuidpb.Generate()) + other := NewSet(uuidpb.Generate()) subject = subject.Diff(other) }, "diff with nil set": func(t *rapid.T) { @@ -163,7 +163,7 @@ func TestSet(t *testing.T) { added := uuidpb.Generate() var shared *uuidpb.UUID - other := uuidpb.NewSet(added) + other := NewSet(added) if !subject.IsEmpty() { v := xrapid.SampledFromSeq(maps.Keys(expected)).Draw(t, "common member") @@ -202,10 +202,10 @@ func TestSet(t *testing.T) { }) t.Run("func String()", func(t *testing.T) { - v1 := MustParse("e9ba3d40-273f-445b-a2b5-0498beb6953c") - v2 := MustParse("015ab018-80aa-4c31-982c-48e19a4d5a49") + v1 := uuidpb.MustParse("e9ba3d40-273f-445b-a2b5-0498beb6953c") + v2 := uuidpb.MustParse("015ab018-80aa-4c31-982c-48e19a4d5a49") - subject := uuidpb.NewSet(v1, v2) + subject := NewSet(v1, v2) got := subject.String() want := `{015ab018-80aa-4c31-982c-48e19a4d5a49, e9ba3d40-273f-445b-a2b5-0498beb6953c}` @@ -215,12 +215,12 @@ func TestSet(t *testing.T) { }) t.Run("func GoString()", func(t *testing.T) { - v1 := MustParse("e9ba3d40-273f-445b-a2b5-0498beb6953c") - v2 := MustParse("015ab018-80aa-4c31-982c-48e19a4d5a49") + v1 := uuidpb.MustParse("e9ba3d40-273f-445b-a2b5-0498beb6953c") + v2 := uuidpb.MustParse("015ab018-80aa-4c31-982c-48e19a4d5a49") - subject := uuidpb.NewSet(v1, v2) + subject := NewSet(v1, v2) got := subject.GoString() - want := `uuidpb.NewSet(uuidpb.MustParse("015ab018-80aa-4c31-982c-48e19a4d5a49"), uuidpb.MustParse("e9ba3d40-273f-445b-a2b5-0498beb6953c"))` + want := `uuidcollection.NewSet(uuidpb.MustParse("015ab018-80aa-4c31-982c-48e19a4d5a49"), uuidpb.MustParse("e9ba3d40-273f-445b-a2b5-0498beb6953c"))` if got != want { t.Fatalf("unexpected GoString() output: got %q, want %q", got, want) diff --git a/x/xrapid/envelope.go b/x/xrapid/envelope.go index 46b5dd47..0935b56e 100644 --- a/x/xrapid/envelope.go +++ b/x/xrapid/envelope.go @@ -1,8 +1,8 @@ package xrapid import ( - "github.com/dogmatiq/enginekit/protobuf/envelopepb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/envelopepb" + "github.com/dogmatiq/protobuf/uuidpb" anypb "google.golang.org/protobuf/types/known/anypb" "pgregory.net/rapid" ) diff --git a/x/xrapid/identity.go b/x/xrapid/identity.go index a20407ea..af98f9c1 100644 --- a/x/xrapid/identity.go +++ b/x/xrapid/identity.go @@ -1,8 +1,8 @@ package xrapid import ( - "github.com/dogmatiq/enginekit/protobuf/identitypb" - "github.com/dogmatiq/enginekit/protobuf/uuidpb" + "github.com/dogmatiq/protobuf/identitypb" + "github.com/dogmatiq/protobuf/uuidpb" "pgregory.net/rapid" )