Documentation ¶
Overview ¶
Package protoparse provides functionality for parsing *.proto source files into descriptors that can be used with other protoreflect packages, like dynamic messages and dynamic GRPC clients.
This package links in other packages that include compiled descriptors for the various "google/protobuf/*.proto" files that are included with protoc. That way, like when invoking protoc, programs need not supply copies of these "builtin" files. Though if copies of the files are provided, they will be used instead of the builtin descriptors.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidSource = errors.New("parse failed: invalid proto source")
ErrInvalidSource is a sentinel error that is returned by calls to Parser.ParseFiles and Parser.ParseFilesButDoNotLink in the event that syntax or link errors are encountered, but the parser's configured ErrorReporter always returns nil.
var ErrNoSyntax = errors.New("no syntax specified; defaulting to proto2 syntax")
ErrNoSyntax is a sentinel error that may be passed to a warning reporter. The error the reporter receives will be wrapped with source position that indicates the file that had no syntax statement.
Functions ¶
func ResolveFilenames ¶
ResolveFilenames tries to resolve fileNames into paths that are relative to directories in the given importPaths. The returned slice has the results in the same order as they are supplied in fileNames.
The resulting names should be suitable for passing to Parser.ParseFiles.
If no import paths are given and any file name is absolute, this returns an error. If no import paths are given and all file names are relative, this returns the original file names. If a file name is already relative to one of the given import paths, it will be unchanged in the returned slice. If a file name given is relative to the current working directory, it will be made relative to one of the given import paths; but if it cannot be made relative (due to no matching import path), an error will be returned.
Types ¶
type ErrorReporter ¶
type ErrorReporter func(err ErrorWithPos) error
ErrorReporter is responsible for reporting the given error. If the reporter returns a non-nil error, parsing/linking will abort with that error. If the reporter returns nil, parsing will continue, allowing the parser to try to report as many syntax and/or link errors as it can find.
type ErrorWithPos ¶
ErrorWithPos is an error about a proto source file that includes information about the location in the file that caused the error.
The value of Error() will contain both the SourcePos and Underlying error. The value of Unwrap() will only be the Underlying error.
type ErrorWithSourcePos ¶
ErrorWithSourcePos is an error about a proto source file that includes information about the location in the file that caused the error.
Errors that include source location information *might* be of this type. However, calling code that is trying to examine errors with location info should instead look for instances of the ErrorWithPos interface, which will find other kinds of errors. This type is only exported for backwards compatibility.
SourcePos should always be set and never nil.
func (ErrorWithSourcePos) Error ¶
func (e ErrorWithSourcePos) Error() string
Error implements the error interface
func (ErrorWithSourcePos) GetPosition ¶
func (e ErrorWithSourcePos) GetPosition() SourcePos
GetPosition implements the ErrorWithPos interface, supplying a location in proto source that caused the error.
func (ErrorWithSourcePos) Unwrap ¶
func (e ErrorWithSourcePos) Unwrap() error
Unwrap implements the ErrorWithPos interface, supplying the underlying error. This error will not include location information.
type FileAccessor ¶
type FileAccessor func(filename string) (io.ReadCloser, error)
FileAccessor is an abstraction for opening proto source files. It takes the name of the file to open and returns either the input reader or an error.
func FileContentsFromMap ¶
func FileContentsFromMap(files map[string]string) FileAccessor
FileContentsFromMap returns a FileAccessor that uses the given map of file contents. This allows proto source files to be constructed in memory and easily supplied to a parser. The map keys are the paths to the proto source files, and the values are the actual proto source contents.
type Parser ¶
type Parser struct { // The paths used to search for dependencies that are referenced in import // statements in proto source files. If no import paths are provided then // "." (current directory) is assumed to be the only import path. // // This setting is only used during ParseFiles operations. Since calls to // ParseFilesButDoNotLink do not link, there is no need to load and parse // dependencies. ImportPaths []string // If true, the supplied file names/paths need not necessarily match how the // files are referenced in import statements. The parser will attempt to // match import statements to supplied paths, "guessing" the import paths // for the files. Note that this inference is not perfect and link errors // could result. It works best when all proto files are organized such that // a single import path can be inferred (e.g. all files under a single tree // with import statements all being relative to the root of this tree). InferImportPaths bool // LookupImport is a function that accepts a filename and // returns a file descriptor, which will be consulted when resolving imports. // This allows a compiled Go proto in another Go module to be referenced // in the proto(s) being parsed. // // In the event of a filename collision, Accessor is consulted first, // then LookupImport is consulted, and finally the well-known protos // are used. // // For example, in order to automatically look up compiled Go protos that // have been imported and be able to use them as imports, set this to // desc.LoadFileDescriptor. LookupImport func(string) (*desc.FileDescriptor, error) // Used to create a reader for a given filename, when loading proto source // file contents. If unset, os.Open is used. If ImportPaths is also empty // then relative paths are will be relative to the process's current working // directory. Accessor FileAccessor // If true, the resulting file descriptors will retain source code info, // that maps elements to their location in the source files as well as // includes comments found during parsing (and attributed to elements of // the source file). IncludeSourceCodeInfo bool // If true, the results from ParseFilesButDoNotLink will be passed through // some additional validations. But only constraints that do not require // linking can be checked. These include proto2 vs. proto3 language features, // looking for incorrect usage of reserved names or tags, and ensuring that // fields have unique tags and that enum values have unique numbers (unless // the enum allows aliases). ValidateUnlinkedFiles bool // If true, the results from ParseFilesButDoNotLink will have options // interpreted. Any uninterpretable options (including any custom options or // options that refer to message and enum types, which can only be // interpreted after linking) will be left in uninterpreted_options. Also, // the "default" pseudo-option for fields can only be interpreted for scalar // fields, excluding enums. (Interpreting default values for enum fields // requires resolving enum names, which requires linking.) InterpretOptionsInUnlinkedFiles bool // A custom reporter of syntax and link errors. If not specified, the // default reporter just returns the reported error, which causes parsing // to abort after encountering a single error. // // The reporter is not invoked for system or I/O errors, only for syntax and // link errors. ErrorReporter ErrorReporter // A custom reporter of warnings. If not specified, warning messages are ignored. WarningReporter WarningReporter }
Parser parses proto source into descriptors.
func (Parser) ParseFiles ¶
func (p Parser) ParseFiles(filenames ...string) ([]*desc.FileDescriptor, error)
ParseFiles parses the named files into descriptors. The returned slice has the same number of entries as the give filenames, in the same order. So the first returned descriptor corresponds to the first given name, and so on.
All dependencies for all specified files (including transitive dependencies) must be accessible via the parser's Accessor or a link error will occur. The exception to this rule is that files can import standard Google-provided files -- e.g. google/protobuf/*.proto -- without needing to supply sources for these files. Like protoc, this parser has a built-in version of these files it can use if they aren't explicitly supplied.
If the Parser has no ErrorReporter set and a syntax or link error occurs, parsing will abort with the first such error encountered. If there is an ErrorReporter configured and it returns non-nil, parsing will abort with the error it returns. If syntax or link errors are encountered but the configured ErrorReporter always returns nil, the parse fails with ErrInvalidSource.
func (Parser) ParseFilesButDoNotLink ¶
func (p Parser) ParseFilesButDoNotLink(filenames ...string) ([]*dpb.FileDescriptorProto, error)
ParseFilesButDoNotLink parses the named files into descriptor protos. The results are just protos, not fully-linked descriptors. It is possible that descriptors are invalid and still be returned in parsed form without error due to the fact that the linking step is skipped (and thus many validation steps omitted).
There are a few side effects to not linking the descriptors:
- No options will be interpreted. Options can refer to extensions or have message and enum types. Without linking, these extension and type references are not resolved, so the options may not be interpretable. So all options will appear in UninterpretedOption fields of the various descriptor options messages.
- Type references will not be resolved. This means that the actual type names in the descriptors may be unqualified and even relative to the scope in which the type reference appears. This goes for fields that have message and enum types. It also applies to methods and their references to request and response message types.
- Enum fields are not known. Until a field's type reference is resolved (during linking), it is not known whether the type refers to a message or an enum. So all fields with such type references have their Type set to TYPE_MESSAGE.
This method will still validate the syntax of parsed files. If the parser's ValidateUnlinkedFiles field is true, additional checks, beyond syntax will also be performed.
If the Parser has no ErrorReporter set and a syntax or link error occurs, parsing will abort with the first such error encountered. If there is an ErrorReporter configured and it returns non-nil, parsing will abort with the error it returns. If syntax or link errors are encountered but the configured ErrorReporter always returns nil, the parse fails with ErrInvalidSource.
type WarningReporter ¶
type WarningReporter func(ErrorWithPos)
WarningReporter is responsible for reporting the given warning. This is used for indicating non-error messages to the calling program for things that do not cause the parse to fail but are considered bad practice. Though they are just warnings, the details are supplied to the reporter via an error type.