Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve docs for protosourcepath package #3394

Merged
merged 1 commit into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion private/buf/buftarget/controlling_workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ControllingWorkspace interface {
// buf.work.yaml or v2 buf.yaml workspace configuration is located.
Path() string
// Returns a buf.work.yaml file that was found for the controlling workspace.
// This is empty if we are retruning a buf.yaml.
// This is empty if we are returning a buf.yaml.
BufWorkYAMLFile() bufconfig.BufWorkYAMLFile
// Returns a buf.yaml that was found for the controlling workspace.
// This is empty if we are returning a buf.work.yaml.
Expand Down
2 changes: 1 addition & 1 deletion private/bufpkg/bufprotoplugin/bufprotoplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type PluginResponse struct {
PluginOut string
}

// NewPluginResponse retruns a new *PluginResponse.
// NewPluginResponse returns a new *PluginResponse.
func NewPluginResponse(
response *pluginpb.CodeGeneratorResponse,
pluginName string,
Expand Down
269 changes: 96 additions & 173 deletions private/pkg/protosourcepath/README.md

Large diffs are not rendered by default.

36 changes: 23 additions & 13 deletions private/pkg/protosourcepath/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,46 +27,56 @@ const (
enumReservedNameTypeTag = int32(5)
)

// enums is the state when an element representing enums in the source path was parsed.
func enums(
_ int32,
sourcePath protoreflect.SourcePath,
i int,
fullSourcePath protoreflect.SourcePath,
index int,
excludeChildAssociatedPaths bool,
) (state, []protoreflect.SourcePath, error) {
associatedPaths := []protoreflect.SourcePath{
currentPath(sourcePath, i),
currentPath(fullSourcePath, index),
}
if !excludeChildAssociatedPaths {
associatedPaths = append(
associatedPaths,
childAssociatedPath(sourcePath, i, enumNameTypeTag),
childAssociatedPath(fullSourcePath, index, enumNameTypeTag),
)
}
if len(sourcePath) == i+1 {
if len(fullSourcePath) == index+1 {
// This path does not extend beyond the enum declaration, return associated paths and
// terminate here.
return nil, associatedPaths, nil
}
return enum, associatedPaths, nil
}

func enum(token int32, sourcePath protoreflect.SourcePath, i int, _ bool) (state, []protoreflect.SourcePath, error) {
// enum is the state when an element representing a specific child path of an enum was parsed.
func enum(token int32, fullSourcePath protoreflect.SourcePath, index int, _ bool) (state, []protoreflect.SourcePath, error) {
switch token {
case enumNameTypeTag:
// The enum name has already been added, can terminate here immediately.
return nil, nil, nil
case enumValuesTypeTag:
if len(sourcePath) < i+2 {
return nil, nil, newInvalidSourcePathError(sourcePath, "cannot have enum value declaration without index")
// We check to make sure that the length of the source path contains at least the current
// token and an index. This is because all source paths for enum values are expected
// to have indices.
if len(fullSourcePath) < index+2 {
return nil, nil, newInvalidSourcePathError(fullSourcePath, "cannot have enum value declaration without index")
}
return enumValues, nil, nil
case enumOptionTypeTag:
// Return the entire path and then handle the option
return options, []protoreflect.SourcePath{slicesext.Copy(sourcePath)}, nil
// For options, we add the full path and then return the options state to validate
// the path.
return options, []protoreflect.SourcePath{slicesext.Copy(fullSourcePath)}, nil
case enumReservedRangeTypeTag:
return reservedRanges, []protoreflect.SourcePath{currentPath(sourcePath, i)}, nil
// For reserved ranges, we add the full path and then return the reserved ranges state to
// validate the path.
return reservedRanges, []protoreflect.SourcePath{currentPath(fullSourcePath, index)}, nil
case enumReservedNameTypeTag:
return reservedNames, []protoreflect.SourcePath{currentPath(sourcePath, i)}, nil
// For reserved names, we add the full path and then return the reserved names state to
// validate the path.
return reservedNames, []protoreflect.SourcePath{currentPath(fullSourcePath, index)}, nil
}
return nil, nil, newInvalidSourcePathError(sourcePath, "invalid enum path")
return nil, nil, newInvalidSourcePathError(fullSourcePath, "invalid enum path")
}
19 changes: 12 additions & 7 deletions private/pkg/protosourcepath/enumvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,34 @@ var (
}
)

// enumValues is the state when an element representing enum values in the source path was
// parsed.
func enumValues(
_ int32,
sourcePath protoreflect.SourcePath,
i int,
fullSourcePath protoreflect.SourcePath,
index int,
excludeChildAssociatedPaths bool,
) (state, []protoreflect.SourcePath, error) {
associatedPaths := []protoreflect.SourcePath{
currentPath(sourcePath, i),
currentPath(fullSourcePath, index),
}
if !excludeChildAssociatedPaths {
associatedPaths = append(
associatedPaths,
childAssociatedPath(sourcePath, i, enumValueNameTypeTag),
childAssociatedPath(sourcePath, i, enumValueNumberTypeTag),
childAssociatedPath(fullSourcePath, index, enumValueNameTypeTag),
childAssociatedPath(fullSourcePath, index, enumValueNumberTypeTag),
)
}
if len(sourcePath) == i+1 {
if len(fullSourcePath) == index+1 {
// This does not extend beyond the enum value declaration, return associated paths and
// terminate here.
return nil, associatedPaths, nil
}
return enumValue, associatedPaths, nil
}

// enumValue is the state when an element representing a specific child path of an enum was
// parsed.
func enumValue(token int32, sourcePath protoreflect.SourcePath, i int, _ bool) (state, []protoreflect.SourcePath, error) {
// TODO: use slices.Contains in the future
if slicesext.ElementsContained(
Expand All @@ -67,7 +71,8 @@ func enumValue(token int32, sourcePath protoreflect.SourcePath, i int, _ bool) (
}
switch token {
case enumValueOptionTypeTag:
// Return the entire path and then handle the option
// For options, we add the full path and then return the options state to validate
// the path.
return options, []protoreflect.SourcePath{slicesext.Copy(sourcePath)}, nil
}
return nil, nil, newInvalidSourcePathError(sourcePath, "invalid enum value path")
Expand Down
45 changes: 26 additions & 19 deletions private/pkg/protosourcepath/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,36 @@ var (
}
)

// fields is the state when an element representing fields in the source path was parsed.
func fields(
_ int32,
sourcePath protoreflect.SourcePath,
i int,
fullSourcePath protoreflect.SourcePath,
index int,
excludeChildAssociatedPaths bool,
) (state, []protoreflect.SourcePath, error) {
associatedPaths := []protoreflect.SourcePath{
currentPath(sourcePath, i),
currentPath(fullSourcePath, index),
}
if !excludeChildAssociatedPaths {
associatedPaths = append(
associatedPaths,
childAssociatedPath(sourcePath, i, fieldNameTypeTag),
childAssociatedPath(sourcePath, i, fieldNumberTypeTag),
childAssociatedPath(sourcePath, i, fieldLabelTypeTag),
childAssociatedPath(sourcePath, i, fieldTypeTypeTag),
childAssociatedPath(sourcePath, i, fieldTypeNameTypeTag),
childAssociatedPath(fullSourcePath, index, fieldNameTypeTag),
childAssociatedPath(fullSourcePath, index, fieldNumberTypeTag),
childAssociatedPath(fullSourcePath, index, fieldLabelTypeTag),
childAssociatedPath(fullSourcePath, index, fieldTypeTypeTag),
childAssociatedPath(fullSourcePath, index, fieldTypeNameTypeTag),
)
}
if len(sourcePath) == i+1 {
if len(fullSourcePath) == index+1 {
// This does not extend beyond the field declaration, return the associated paths and
// terminate here.
return nil, associatedPaths, nil
}
return field, associatedPaths, nil
}

func field(token int32, sourcePath protoreflect.SourcePath, i int, _ bool) (state, []protoreflect.SourcePath, error) {
// field is the state when an element representing a specific child path of a field was parsed.
func field(token int32, fullSourcePath protoreflect.SourcePath, index int, _ bool) (state, []protoreflect.SourcePath, error) {
// TODO: use slices.Contains in the future
if slicesext.ElementsContained(
terminalFieldTokens,
Expand All @@ -79,29 +81,34 @@ func field(token int32, sourcePath protoreflect.SourcePath, i int, _ bool) (stat
}
switch token {
case fieldOptionTypeTag:
// Return the entire path and then handle the option
return options, []protoreflect.SourcePath{slicesext.Copy(sourcePath)}, nil
// For options, we add the full path and then return the options state to validate
// the path.
return options, []protoreflect.SourcePath{slicesext.Copy(fullSourcePath)}, nil
case fieldDefaultValueTypeTag:
return nil, []protoreflect.SourcePath{currentPath(sourcePath, i)}, nil
// Default value is a terminal path, but was not already added to our associated paths,
// since default values are specific to proto2. Add the path and terminate.
return nil, []protoreflect.SourcePath{currentPath(fullSourcePath, index)}, nil
}
return nil, nil, newInvalidSourcePathError(sourcePath, "invalid field path")
return nil, nil, newInvalidSourcePathError(fullSourcePath, "invalid field path")
}

// extensions is the state when an element representing extensions in the source path was parsed.
func extensions(
token int32,
sourcePath protoreflect.SourcePath,
i int,
fullSourcePath protoreflect.SourcePath,
index int,
excludeChildAssociatedPaths bool,
) (state, []protoreflect.SourcePath, error) {
// An extension is effectively a field descriptor, so we start by getting all paths for fields.
field, associatedPaths, err := fields(token, sourcePath, i, excludeChildAssociatedPaths)
// Extensions share the same descriptor proto definition as fields, so we can parse them
// using the same states.
field, associatedPaths, err := fields(token, fullSourcePath, index, excludeChildAssociatedPaths)
if err != nil {
return nil, nil, err
}
if !excludeChildAssociatedPaths {
associatedPaths = append(
associatedPaths,
childAssociatedPath(sourcePath, i, extensionExtendeeTypeTag),
childAssociatedPath(fullSourcePath, index, extensionExtendeeTypeTag),
)
}
return field, associatedPaths, nil
Expand Down
Loading