protoiter

package module
v1.0.0-beta.0 Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2024 License: Apache-2.0 Imports: 2 Imported by: 0

README

protoiter

protoiter is a Go package that provides generic iterator functions for Protocol Buffers reflection, leveraging the new iter package introduced in Go 1.23.

Go Reference Go Report Card

Overview

The package offers a set of utility functions to create iterators for various Protocol Buffers entities, including:

  • Descriptors
  • Enum Types
  • Extension Types
  • Files
  • Message Fields
  • Message Types

Usage Example

package main

import (
    "fmt"
    "iter"

    "github.com/goaux/protoiter"
    "google.golang.org/protobuf/reflect/protoreflect"
)

func main() {
    // Assuming you have a collection of descriptors
    for i, descriptor := range protoiter.Each(yourDescriptorCollection) {
        fmt.Printf("Index: %d, Descriptor: %v\n", i, descriptor)
    }
}

Documentation

Overview

Package protoiter provides generic iterator functions for Protocol Buffers reflection.

Example
package main

import (
	"github.com/goaux/protoiter"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
	"google.golang.org/protobuf/types/descriptorpb"
)

func main() {
	var _ protoiter.Files = protoregistry.GlobalFiles
	var _ protoiter.Types = protoregistry.GlobalTypes
	var _ descriptorpb.DescriptorProto

	for file := range protoiter.EachFile(protoregistry.GlobalFiles) {
		var _ protoreflect.FileDescriptor = file
		for field, value := range protoiter.EachField(file.Options().ProtoReflect()) {
			var _ protoreflect.FieldDescriptor = field
			var _ protoreflect.Value = value
		}
		for i, enum := range protoiter.Each(file.Enums()) {
			var _ int = i
			var _ protoreflect.EnumDescriptor = enum
			for field, value := range protoiter.EachField(enum.Options().ProtoReflect()) {
				var _ protoreflect.FieldDescriptor = field
				var _ protoreflect.Value = value
			}
		}
		for i, message := range protoiter.Each(file.Messages()) {
			var _ int = i
			var _ protoreflect.MessageDescriptor = message
			for field, value := range protoiter.EachField(message.Options().ProtoReflect()) {
				var _ protoreflect.FieldDescriptor = field
				var _ protoreflect.Value = value
			}
			for i, oneof := range protoiter.Each(message.Oneofs()) {
				var _ int = i
				var _ protoreflect.OneofDescriptor = oneof
				for field, value := range protoiter.EachField(oneof.Options().ProtoReflect()) {
					var _ protoreflect.FieldDescriptor = field
					var _ protoreflect.Value = value
				}
			}
		}
		for i, extension := range protoiter.Each(file.Extensions()) {
			var _ int = i
			var _ protoreflect.ExtensionDescriptor = extension
			for field, value := range protoiter.EachField(extension.Options().ProtoReflect()) {
				var _ protoreflect.FieldDescriptor = field
				var _ protoreflect.Value = value
			}
		}
		for i, service := range protoiter.Each(file.Services()) {
			var _ int = i
			var _ protoreflect.ServiceDescriptor = service
			for field, value := range protoiter.EachField(service.Options().ProtoReflect()) {
				var _ protoreflect.FieldDescriptor = field
				var _ protoreflect.Value = value
			}
			for i, method := range protoiter.Each(service.Methods()) {
				var _ int = i
				var _ protoreflect.MethodDescriptor = method
				for field, value := range protoiter.EachField(method.Options().ProtoReflect()) {
					var _ protoreflect.FieldDescriptor = field
					var _ protoreflect.Value = value
				}
			}
		}
	}

	for file := range protoiter.EachFileByPackage(protoregistry.GlobalFiles, "") {
		var _ protoreflect.FileDescriptor = file
	}

	for enum := range protoiter.EachEnum(protoregistry.GlobalTypes) {
		var _ protoreflect.EnumType = enum
	}
	for message := range protoiter.EachMessage(protoregistry.GlobalTypes) {
		var _ protoreflect.MessageType = message
	}
	for extension := range protoiter.EachExtension(protoregistry.GlobalTypes) {
		var _ protoreflect.ExtensionType = extension
	}
	for extension := range protoiter.EachExtensionByMessage(protoregistry.GlobalTypes, "") {
		var _ protoreflect.ExtensionType = extension
	}
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Each

func Each[DD Descriptors[D], D protoreflect.Descriptor](dd DD) iter.Seq2[int, D]

Each creates a sequential iterator over a collection of descriptors. It allows iterating through descriptors with their indices.

Parameters:

  • dd: A collection of descriptors implementing the Descriptors interface

Returns:

  • An iterator sequence that yields the index and descriptor for each item
Example
package main

import (
	"fmt"

	"github.com/goaux/protoiter"
	"github.com/goaux/results"
	"google.golang.org/protobuf/reflect/protoregistry"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func main() {
	var _ timestamppb.Timestamp
	file := results.Must1(protoregistry.GlobalFiles.FindFileByPath("google/protobuf/timestamp.proto"))
	for i, message := range protoiter.Each(file.Messages()) {
		fmt.Println(i, message.FullName())
	}
}
Output:

0 google.protobuf.Timestamp

func EachEnum

func EachEnum(types Types) iter.Seq[protoreflect.EnumType]

EachEnum creates a sequential iterator over enum types.

It returns an iterator of calling google.golang.org/protobuf/reflect/protoregistry.Types.RangeEnums.

RangeEnums iterates over all registered enums while f returns true. Iteration order is undefined.

Parameters:

  • types: A Types implementation providing access to enum types

Returns:

  • An iterator sequence that yields each enum type
Example
package main

import (
	"github.com/goaux/protoiter"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

func main() {
	for enumType := range protoiter.EachEnum(protoregistry.GlobalTypes) {
		var _ protoreflect.EnumType = enumType
	}
}

func EachExtension

func EachExtension(types Types) iter.Seq[protoreflect.ExtensionType]

EachExtension creates a sequential iterator over extension types.

It returns an iterator of calling google.golang.org/protobuf/reflect/protoregistry.Types.RangeExtensions.

RangeExtensions iterates over all registered extensions while f returns true. Iteration order is undefined.

Parameters:

  • types: A Types implementation providing access to extension types

Returns:

  • An iterator sequence that yields each extension type
Example
package main

import (
	"github.com/goaux/protoiter"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

func main() {
	for extensionType := range protoiter.EachExtension(protoregistry.GlobalTypes) {
		var _ protoreflect.ExtensionType = extensionType
	}
}

func EachExtensionByMessage

func EachExtensionByMessage(types Types, message protoreflect.FullName) iter.Seq[protoreflect.ExtensionType]

EachExtensionByMessage creates a sequential iterator over extension types for a specific message.

It returns an iterator of calling google.golang.org/protobuf/reflect/protoregistry.Types.RangeExtensionsByMessage.

RangeExtensionsByMessage iterates over all registered extensions filtered by a given message type while f returns true. Iteration order is undefined.

Parameters:

  • types: A Types implementation providing access to extension types
  • message: The full name of the message to filter extension types

Returns:

  • An iterator sequence that yields extension types for the specified message

func EachField

EachField creates a sequential iterator over fields in a protocol buffer message.

It returns an iterator of calling protoreflect.Message.Range.

Range iterates over every populated field in an undefined order,
calling f for each field descriptor and value encountered.
Range returns immediately if f returns false.
While iterating, mutating operations may only be performed
on the current field descriptor.

Parameters:

  • message: The protocol buffer message to iterate over

Returns:

  • An iterator sequence that yields each field descriptor and its corresponding value
Example
package main

import (
	"fmt"
	"reflect"
	"time"

	"github.com/goaux/protoiter"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func main() {
	now := timestamppb.New(time.Unix(123, 456))
	for field, value := range protoiter.EachField(now.ProtoReflect()) {
		fmt.Println(field.FullName(), value, reflect.TypeOf(value.Interface()))
	}
}
Output:

google.protobuf.Timestamp.seconds 123 int64
google.protobuf.Timestamp.nanos 456 int32

func EachFile

func EachFile(files Files) iter.Seq[protoreflect.FileDescriptor]

EachFile creates a sequential iterator over all file descriptors.

It returns an iterator of calling google.golang.org/protobuf/reflect/protoregistry.Files.RangeFiles.

RangeFiles iterates over all registered files while f returns true. If multiple files have the same name, RangeFiles iterates over all of them. The iteration order is undefined.

Parameters:

  • files: A Files implementation providing access to file descriptors

Returns:

  • An iterator sequence that yields each file descriptor
Example
package main

import (
	"github.com/goaux/protoiter"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

func main() {
	for file := range protoiter.EachFile(protoregistry.GlobalFiles) {
		var _ protoreflect.FileDescriptor = file
	}
}

func EachFileByPackage

func EachFileByPackage(files Files, name protoreflect.FullName) iter.Seq[protoreflect.FileDescriptor]

EachFileByPackage creates a sequential iterator over file descriptors in a specific package.

It returns an iterator of calling google.golang.org/protobuf/reflect/protoregistry.Files.RangeFilesByPackage.

RangeFilesByPackage iterates over all registered files in a given proto package while f returns true. The iteration order is undefined.

Parameters:

  • files: A Files implementation providing access to file descriptors
  • name: The full package name to filter file descriptors

Returns:

  • An iterator sequence that yields file descriptors within the specified package

func EachMessage

func EachMessage(types Types) iter.Seq[protoreflect.MessageType]

EachMessage creates a sequential iterator over message types.

It returns an iterator of calling google.golang.org/protobuf/reflect/protoregistry.Types.RangeMessages.

RangeMessages iterates over all registered messages while f returns true. Iteration order is undefined.

Parameters:

  • types: A Types implementation providing access to message types

Returns:

  • An iterator sequence that yields each message type
Example
package main

import (
	"github.com/goaux/protoiter"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

func main() {
	for messageType := range protoiter.EachMessage(protoregistry.GlobalTypes) {
		var _ protoreflect.MessageType = messageType
	}
}

Types

type Descriptors

type Descriptors[Descriptor protoreflect.Descriptor] interface {
	Len() int
	Get(int) Descriptor
}

Descriptors is an interface that abstracts the methods required to create an iterator over protoreflect.Descriptors.

It defines a generic way to access a collection of descriptors with a length and retrieval method. Descriptor is a generic type parameter representing the specific descriptor type (e.g. FileDescriptor, MessageDescriptor).

type Files

type Files interface {
	RangeFiles(f func(protoreflect.FileDescriptor) bool)
	RangeFilesByPackage(name protoreflect.FullName, f func(protoreflect.FileDescriptor) bool)
}

Files is an interface that abstracts the methods required to create an iterator over google.golang.org/protobuf/reflect/protoregistry.Files.

type Types

type Types interface {
	RangeEnums(f func(protoreflect.EnumType) bool)
	RangeMessages(f func(protoreflect.MessageType) bool)
	RangeExtensions(f func(protoreflect.ExtensionType) bool)
	RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool)
}

Types is an interface that abstracts the methods required to create an iterator over google.golang.org/protobuf/reflect/protoregistry.Types.

It provides methods to range over different types of protocol buffer descriptors.

Jump to

Keyboard shortcuts

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