plugins

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Feb 15, 2022 License: Apache-2.0 Imports: 18 Imported by: 7

Documentation

Overview

Package plugins contains functions that protoc plugins can use to simplify the task of implementing the plugin interface and generating Go code.

Interface for Protoc Plugins

A protoc plugin need only provide a function whose signature matches the Plugin type and then wire it up in a main method like so:

func main() {
    output := os.Stdout
    os.Stdout = os.Stderr
    err := plugins.RunPlugin(os.Args[0], doCodeGen, os.Stdin, output)
    if err != nil {
        os.Exit(1)
    }
}

func doCodeGen(req  *plugins.CodeGenRequest,
               resp *plugins.CodeGenResponse) error {
    // ...
    // Process req, generate code to resp
    // ...
}

Code Generation Helpers

This package has numerous helpful types for generating Go code. For example, GoNames provides numerous functions for computing the names and types of elements generated by the standard protoc-gen-go plugin. This makes it easy to generate code that references these types and/or augments these types.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CamelCase

func CamelCase(s string) string

CamelCase converts the given symbol to an exported Go symbol in camel-case convention. It removes underscores and makes letters following an underscore upper-case. If the given symbol starts with an underscore, the underscore is replaced with a capital "X".

func Exec

func Exec(ctx context.Context, pluginPath string, req *CodeGenRequest, resp *CodeGenResponse) error

Exec executes the protoc plugin at the given path, sending it the given request and adding its generated code output to the given response.

func PluginMain

func PluginMain(plugin Plugin)

PluginMain should be called from main functions of protoc plugins that are written in Go. This will handle invoking the given plugin function, handling any errors, writing the results to the process's stdout, and then exiting the process.

func RunPlugin

func RunPlugin(name string, plugin Plugin, in io.Reader, out io.Writer) error

RunPlugin runs the given plugin. Errors are reported using the given name. The protoc request is read from in and the plugin's results are written to out. Under most circumstances, this function will return nil, even if an error was encountered. That is because typically errors will be reported to out, by writing a code gen response that indicates the error. But if that fails, a non-nil error will be returned.

Types

type CodeGenRequest

type CodeGenRequest struct {
	// Args are the parameters for the plugin.
	Args []string
	// Files are the proto source files for which code should be generated.
	Files []*desc.FileDescriptor
	// The version of protoc that has invoked the plugin.
	ProtocVersion ProtocVersion
}

CodeGenRequest represents the arguments to protoc that describe what code protoc has been requested to generate.

type CodeGenResponse

type CodeGenResponse struct {
	// contains filtered or unexported fields
}

CodeGenResponse is how the plugin transmits generated code to protoc.

func NewCodeGenResponse

func NewCodeGenResponse(pluginName string, other *CodeGenResponse) *CodeGenResponse

NewCodeGenResponse creates a new response for the named plugin. If other is non-nil, files added to the returned response will be contributed to other.

func (*CodeGenResponse) ForEach

func (resp *CodeGenResponse) ForEach(fn func(name, insertionPoint string, data io.Reader) error) error

ForEach invokes the given function for each output in the response so far. The given reader provides access to examine the file/snippet contents. If the function returns an error, ForEach stops iteration and returns that error.

func (*CodeGenResponse) OutputFile

func (resp *CodeGenResponse) OutputFile(name string) io.Writer

OutputFile returns a writer for creating the file with the given name.

func (*CodeGenResponse) OutputSnippet

func (resp *CodeGenResponse) OutputSnippet(name, insertionPoint string) io.Writer

OutputSnippet returns a writer for creating the snippet to be stored in the given file name at the given insertion point. Insertion points are generally not used when producing Go code since Go allows multiple files in the same package to all contribute to the package's contents. But insertion points can be valuable for other languages where certain kinds of language elements must appear in particular files or in particular locations within a file.

func (*CodeGenResponse) SupportsFeatures added in v0.5.0

func (resp *CodeGenResponse) SupportsFeatures(feature ...pluginpb.CodeGeneratorResponse_Feature)

SupportsFeatures allows the plugin to communicate which code generation features that it supports.

type GoNames

type GoNames struct {
	// A user-provided map of proto file names to the Go import package where
	// that file's code is generated. These mappings can be specified via
	// "M<protofile>=<gopkg>" args to the "--go_out" protoc argument. Other
	// plugins that generate Go code may support the option, too.
	ImportMap map[string]string

	// The import path prefix that matches the root of the current Go module.
	// When non-empty, this will be stripped from paths returned from the
	// OutputFilenameFor. This path can provided as a "module=<path>" arg to
	// the "--go_out" protoc argument. Other plugins that generate Go code may
	// support this option, too.
	ModuleRoot string

	// When true, output paths computed by OutputFilenameFor using the path
	// of the input source file instead of using its corresponding Go import
	// path. This can be enabled using a "paths=source_relative" arg to the
	// "--go_out" protoc argument. Other plugins that generate Go code may
	// support this option, too.
	//
	// If this flag is true, the ModuleRoot field is ignored.
	SourceRelative bool
	// contains filtered or unexported fields
}

GoNames is a helper for computing the names and types of Go elements that are generated from protocol buffers.

GoNames is not thread-safe.

func (*GoNames) CamelCase

func (n *GoNames) CamelCase(name string) string

CamelCase converts the given identifier to an exported name that uses camel-case. Interior underscores followed by lower-case letters will be changed to upper-case letters. If the name begins with an underscore, it will be replaced with "X" so the resulting identifier is exported without colliding with similar identifier that does not being with an underscore.

func (*GoNames) GoNameOfEnumVal added in v0.3.0

func (n *GoNames) GoNameOfEnumVal(evd *desc.EnumValueDescriptor) gopoet.Symbol

GoNameOfEnumVal returns the name of the constant that represents the given enum value descriptor.

func (*GoNames) GoNameOfExportedServiceDesc added in v0.4.0

func (n *GoNames) GoNameOfExportedServiceDesc(sd *desc.ServiceDescriptor) gopoet.Symbol

GoNameOfExportedServiceDesc returns the newer exported name of the var that holds the grpc.ServiceDesc that describes the given service. As of v1.0 of protoc-gen-go-grpc, this var is exported.

If generating code that needs to reference the older, unexported var (from earlier versions of protoc plugins for Go), use GoNameOfServiceDesc instead.

func (*GoNames) GoNameOfExtensionDesc

func (n *GoNames) GoNameOfExtensionDesc(fld *desc.FieldDescriptor) gopoet.Symbol

GoNameOfExtensionDesc returns the name of the *proto.ExtensionDesc var that represents the given extension field descriptor.

func (*GoNames) GoNameOfField

func (n *GoNames) GoNameOfField(fld *desc.FieldDescriptor) string

GoNameOfField returns the name of the field for the given field descriptor. This will name a field in a message struct or in a single-field struct that satisfies a oneof interface if this field is part of a oneof.

func (*GoNames) GoNameOfMethod

func (n *GoNames) GoNameOfMethod(md *desc.MethodDescriptor) string

GoNameOfMethod returns the name of the Go method corresponding to the given method descriptor. This will be the name of a method in the generated client and server interfaces. (The interfaces will have different signatures for client vs. server, but the same method names.)

func (*GoNames) GoNameOfOneOf

func (n *GoNames) GoNameOfOneOf(ood *desc.OneOfDescriptor) string

GoNameOfOneOf returns the name of the field for the given oneof descriptor.

func (*GoNames) GoNameOfServiceDesc

func (n *GoNames) GoNameOfServiceDesc(sd *desc.ServiceDescriptor) string

GoNameOfServiceDesc returns the legacy unexported name of the var that holds the grpc.ServiceDesc that describes the given service. Prior to v1.0 and of protoc-gen-go-grpc, for generating Go code related to gRPC, these variables were unexported.

This does not return a gopoet.Symbol because the var is not usable outside of the generated package due to its being unexported. So only the symbol's unqualified name is useful.

func (*GoNames) GoPackageForFile

func (n *GoNames) GoPackageForFile(fd *desc.FileDescriptor) gopoet.Package

GoPackageForFile returns the Go package for the given file descriptor. This will use the file's "go_package" option if it has one, but that can be overridden if the user has supplied an entry in n.ImportMap.

func (*GoNames) GoPackageForFileWithOverride added in v0.2.0

func (n *GoNames) GoPackageForFileWithOverride(fd *desc.FileDescriptor, goPackage string) gopoet.Package

GoPackageForFileWithOverride returns the Go package for the given file descriptor, but uses the given string as if it were the "go_package" option value.

func (*GoNames) GoTypeForEnum

func (n *GoNames) GoTypeForEnum(ed *desc.EnumDescriptor) gopoet.TypeName

GoTypeForEnum returns the Go type for the given enum descriptor.

func (*GoNames) GoTypeForMessage

func (n *GoNames) GoTypeForMessage(md *desc.MessageDescriptor) gopoet.TypeName

GoTypeForMessage returns the Go type for the given message descriptor.

func (*GoNames) GoTypeForOneof

func (n *GoNames) GoTypeForOneof(ood *desc.OneOfDescriptor) string

GoTypeForOneof returns the unexported name of the Go interface type for the given oneof descriptor. This interface has numerous types that implement it, each of which can be determined using GoTypeNameForOneofField with the various fields that belong to the oneof.

This does not return a *TypeName because the type is not usable outside of the generated package due to the interface being unexported. So only the interface's unqualified name is useful.

func (*GoNames) GoTypeForOneofChoice

func (n *GoNames) GoTypeForOneofChoice(fld *desc.FieldDescriptor) gopoet.TypeName

GoTypeForOneofChoice returns the single-field struct type that contains the given oneof choice. The returned type implements the oneof interface type named by GoTypeForOneof.

func (*GoNames) GoTypeForServiceClient

func (n *GoNames) GoTypeForServiceClient(sd *desc.ServiceDescriptor) gopoet.TypeName

GoTypeForServiceClient returns the Go type of the generated client interface for the given service descriptor.

func (*GoNames) GoTypeForServiceClientImpl

func (n *GoNames) GoTypeForServiceClientImpl(sd *desc.ServiceDescriptor) string

GoTypeForServiceClientImpl returns the unexported name of the Go struct type that provides the default/generated implementation of the client interface for the given service descriptor.

This does not return a *TypeName because the type is not usable outside of the generated package due to the struct being unexported. So only the struct's unqualified name is useful.

func (*GoNames) GoTypeForServiceServer

func (n *GoNames) GoTypeForServiceServer(sd *desc.ServiceDescriptor) gopoet.TypeName

GoTypeForServiceServer returns the Go type of the generated server interface for the given service descriptor.

func (*GoNames) GoTypeForStreamClient

func (n *GoNames) GoTypeForStreamClient(md *desc.MethodDescriptor) gopoet.TypeName

GoTypeForStreamClient returns the Go type of the generated client stream interface for the given method descriptor. The given method must not be a unary method.

func (*GoNames) GoTypeForStreamClientImpl

func (n *GoNames) GoTypeForStreamClientImpl(md *desc.MethodDescriptor) string

GoTypeForStreamClientImpl returns the unexported name of the Go struct type that provides the default/generated implementation of the client stream interface for the given method descriptor.

This does not return a *TypeName because the type is not usable outside of the generated package due to the struct being unexported. So only the struct's unqualified name is useful.

func (*GoNames) GoTypeForStreamServer

func (n *GoNames) GoTypeForStreamServer(md *desc.MethodDescriptor) gopoet.TypeName

GoTypeForStreamServer returns the Go type of the generated server stream interface for the given method descriptor. The given method must not be a unary method.

func (*GoNames) GoTypeForStreamServerImpl

func (n *GoNames) GoTypeForStreamServerImpl(md *desc.MethodDescriptor) string

GoTypeForStreamServerImpl returns the unexported name of the Go struct type that provides the default/generated implementation of the server stream interface for the given method descriptor.

This does not return a *TypeName because the type is not usable outside of the generated package due to the struct being unexported. So only the struct's unqualified name is useful.

func (*GoNames) GoTypeOfField

func (n *GoNames) GoTypeOfField(fld *desc.FieldDescriptor) gopoet.TypeName

GoTypeOfField returns the Go type of the given field descriptor. This will be the type of the generated field. If fld is an extension, it is the type of allowed values for the extension.

func (*GoNames) GoTypeOfFieldAccessor

func (n *GoNames) GoTypeOfFieldAccessor(fld *desc.FieldDescriptor) gopoet.TypeName

GoTypeOfFieldAccessor returns the Go type of the given field accessor.

func (*GoNames) GoTypeOfRequest

func (n *GoNames) GoTypeOfRequest(md *desc.MethodDescriptor) gopoet.TypeName

GoTypeOfRequest returns the Go type of the request.

func (*GoNames) GoTypeOfResponse

func (n *GoNames) GoTypeOfResponse(md *desc.MethodDescriptor) gopoet.TypeName

GoTypeOfResponse returns the Go type of the response.

func (*GoNames) OutputFilenameFor

func (n *GoNames) OutputFilenameFor(fd *desc.FileDescriptor, suffix string) string

OutputFilenameFor computes an output filename for the given file that has the given suffix/extension. The name includes a path relative to the plugin's output. This method is used to construct the path and name of a file that a protoc plugin will generate.

For example, querying for the suffix ".pb.go" will result in the filename created by the protoc-gen-go plugin.

type Plugin

type Plugin func(*CodeGenRequest, *CodeGenResponse) error

Plugin is a code generator that generates code during protoc invocations. Multiple plugins can be run during the same protoc invocation.

type ProtocVersion

type ProtocVersion struct {
	Major, Minor, Patch int
	Suffix              string
}

ProtocVersion represents a version of the protoc tool.

func (ProtocVersion) String

func (v ProtocVersion) String() string

Jump to

Keyboard shortcuts

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