Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Fix `exclude_type` on a non imported package.
- Fix `--exclude-type` flag for `buf generate` when an input is specified.
- Fix type filter import filtering for options.

## [v1.51.0] - 2025-03-28

Expand Down
2 changes: 1 addition & 1 deletion private/bufpkg/bufimage/bufimageutil/bufimageutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ func (t *transitiveClosure) addElement(
}
oneofFieldCounts[index]++
}
if err := t.exploreCustomOptions(field, referrerFile, imageIndex, opts); err != nil {
if err := t.exploreCustomOptions(field, descriptorInfo.file.Path(), imageIndex, opts); err != nil {
return err
}
}
Expand Down
13 changes: 13 additions & 0 deletions private/bufpkg/bufimage/bufimageutil/bufimageutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,19 @@ func TestConsecutiveFilters(t *testing.T) {
})
}

func TestDependencies(t *testing.T) {
t.Parallel()
// Test referred file for options of imported types.
t.Run("FieldA", func(t *testing.T) {
t.Parallel()
runDiffTest(t, "testdata/deps", "test.FieldA.txtar", WithIncludeTypes("test.FieldA"))
})
t.Run("EnumA", func(t *testing.T) {
t.Parallel()
runDiffTest(t, "testdata/deps", "test.EnumA.txtar", WithIncludeTypes("test.EnumA"))
})
}

func getImage(ctx context.Context, logger *slog.Logger, testdataDir string, options ...bufimage.BuildImageOption) (storage.ReadWriteBucket, bufimage.Image, error) {
bucket, err := storageos.NewProvider().NewReadWriteBucket(testdataDir)
if err != nil {
Expand Down
34 changes: 34 additions & 0 deletions private/bufpkg/bufimage/bufimageutil/testdata/deps/a.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
syntax = "proto3";
package a;

import "b.proto";

option (b.B.file_c).c = "c";

message A {
option (b.message_c).c = "c";

string a = 1 [(b.field_c).c = "c"];

oneof oneof_a {
option (b.oneof_c).c = "c";

string foo = 2;
string bar = 3;
}

enum AEnum {
option (b.enum_c).c = "c";

FOO_ENUM_A = 0;
FOO_ENUM_B = 1 [(b.enum_value_c).c = "c"];
}
}

service AService {
option (b.service_c).c = "c";

rpc Method(A) returns (A) {
option (b.method_c).c = "c";
}
}
34 changes: 34 additions & 0 deletions private/bufpkg/bufimage/bufimageutil/testdata/deps/b.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
syntax = "proto3";
package b;

import "c.proto";
import "google/protobuf/descriptor.proto";

message B {
extend google.protobuf.FileOptions {
optional c.C file_c = 50000;
}
string b = 1;
}

extend google.protobuf.MessageOptions {
optional c.C message_c = 50000;
}
extend google.protobuf.FieldOptions {
optional c.C field_c = 50000;
}
extend google.protobuf.OneofOptions {
optional c.C oneof_c = 50000;
}
extend google.protobuf.EnumOptions {
optional c.C enum_c = 50000;
}
extend google.protobuf.EnumValueOptions {
optional c.C enum_value_c = 50000;
}
extend google.protobuf.ServiceOptions {
optional c.C service_c = 50000;
}
extend google.protobuf.MethodOptions {
optional c.C method_c = 50000;
}
6 changes: 6 additions & 0 deletions private/bufpkg/bufimage/bufimageutil/testdata/deps/c.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
syntax = "proto3";
package c;

message C {
string c = 1;
}
256 changes: 256 additions & 0 deletions private/bufpkg/bufimage/bufimageutil/testdata/deps/test.EnumA.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
-- a.proto --
syntax = "proto3";
package a;
import "b.proto";
option (b.B.file_c) = { c: "c" };
message A {
option (b.message_c) = { c: "c" };
enum AEnum {
option (b.enum_c) = { c: "c" };
FOO_ENUM_A = 0;
FOO_ENUM_B = 1 [(b.enum_value_c) = { c: "c" }];
}
}
-- b.proto --
syntax = "proto3";
package b;
import "c.proto";
import "google/protobuf/descriptor.proto";
message B {
extend google.protobuf.FileOptions {
c.C file_c = 50000;
}
}
extend google.protobuf.EnumOptions {
c.C enum_c = 50000;
}
extend google.protobuf.EnumValueOptions {
c.C enum_value_c = 50000;
}
extend google.protobuf.MessageOptions {
c.C message_c = 50000;
}
-- c.proto --
syntax = "proto3";
package c;
message C {
string c = 1;
}
-- google/protobuf/descriptor.proto --
syntax = "proto2";
package google.protobuf;
option cc_enable_arenas = true;
option csharp_namespace = "Google.Protobuf.Reflection";
option go_package = "google.golang.org/protobuf/types/descriptorpb";
option java_outer_classname = "DescriptorProtos";
option java_package = "com.google.protobuf";
option objc_class_prefix = "GPB";
option optimize_for = SPEED;
message EnumOptions {
optional bool allow_alias = 2;
optional bool deprecated = 3 [default = false];
optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true];
optional FeatureSet features = 7;
repeated UninterpretedOption uninterpreted_option = 999;
extensions 1000 to max;
reserved 5;
}
message EnumValueOptions {
optional bool deprecated = 1 [default = false];
optional FeatureSet features = 2;
optional bool debug_redact = 3 [default = false];
optional FieldOptions.FeatureSupport feature_support = 4;
repeated UninterpretedOption uninterpreted_option = 999;
extensions 1000 to max;
}
message FeatureSet {
optional FieldPresence field_presence = 1 [
edition_defaults = { value: "EXPLICIT", edition: EDITION_LEGACY },
edition_defaults = { value: "IMPLICIT", edition: EDITION_PROTO3 },
edition_defaults = { value: "EXPLICIT", edition: EDITION_2023 },
feature_support = { edition_introduced: EDITION_2023 },
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE
];
optional EnumType enum_type = 2 [
edition_defaults = { value: "CLOSED", edition: EDITION_LEGACY },
edition_defaults = { value: "OPEN", edition: EDITION_PROTO3 },
feature_support = { edition_introduced: EDITION_2023 },
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_ENUM,
targets = TARGET_TYPE_FILE
];
optional RepeatedFieldEncoding repeated_field_encoding = 3 [
edition_defaults = { value: "EXPANDED", edition: EDITION_LEGACY },
edition_defaults = { value: "PACKED", edition: EDITION_PROTO3 },
feature_support = { edition_introduced: EDITION_2023 },
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE
];
optional Utf8Validation utf8_validation = 4 [
edition_defaults = { value: "NONE", edition: EDITION_LEGACY },
edition_defaults = { value: "VERIFY", edition: EDITION_PROTO3 },
feature_support = { edition_introduced: EDITION_2023 },
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE
];
optional MessageEncoding message_encoding = 5 [
edition_defaults = { value: "LENGTH_PREFIXED", edition: EDITION_LEGACY },
feature_support = { edition_introduced: EDITION_2023 },
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_FILE
];
optional JsonFormat json_format = 6 [
edition_defaults = { value: "LEGACY_BEST_EFFORT", edition: EDITION_LEGACY },
edition_defaults = { value: "ALLOW", edition: EDITION_PROTO3 },
feature_support = { edition_introduced: EDITION_2023 },
retention = RETENTION_RUNTIME,
targets = TARGET_TYPE_MESSAGE,
targets = TARGET_TYPE_ENUM,
targets = TARGET_TYPE_FILE
];
enum EnumType {
ENUM_TYPE_UNKNOWN = 0;
OPEN = 1;
CLOSED = 2;
}
enum FieldPresence {
FIELD_PRESENCE_UNKNOWN = 0;
EXPLICIT = 1;
IMPLICIT = 2;
LEGACY_REQUIRED = 3;
}
enum JsonFormat {
JSON_FORMAT_UNKNOWN = 0;
ALLOW = 1;
LEGACY_BEST_EFFORT = 2;
}
enum MessageEncoding {
MESSAGE_ENCODING_UNKNOWN = 0;
LENGTH_PREFIXED = 1;
DELIMITED = 2;
}
enum RepeatedFieldEncoding {
REPEATED_FIELD_ENCODING_UNKNOWN = 0;
PACKED = 1;
EXPANDED = 2;
}
enum Utf8Validation {
UTF8_VALIDATION_UNKNOWN = 0;
VERIFY = 2;
NONE = 3;
reserved 1;
}
extensions 1000 to 9994 [
declaration = {
number: 1000,
full_name: ".pb.cpp",
type: ".pb.CppFeatures"
},
declaration = {
number: 1001,
full_name: ".pb.java",
type: ".pb.JavaFeatures"
},
declaration = {
number: 1002,
full_name: ".pb.go",
type: ".pb.GoFeatures"
},
declaration = {
number: 9990,
full_name: ".pb.proto1",
type: ".pb.Proto1Features"
}
];
extensions 9995 to 9999, 10000;
reserved 999;
}
message FieldOptions {
message FeatureSupport {
optional Edition edition_introduced = 1;
optional Edition edition_deprecated = 2;
optional string deprecation_warning = 3;
optional Edition edition_removed = 4;
}
}
message FileOptions {
optional string java_package = 1;
optional string java_outer_classname = 8;
optional OptimizeMode optimize_for = 9 [default = SPEED];
optional bool java_multiple_files = 10 [default = false];
optional string go_package = 11;
optional bool cc_generic_services = 16 [default = false];
optional bool java_generic_services = 17 [default = false];
optional bool py_generic_services = 18 [default = false];
optional bool java_generate_equals_and_hash = 20 [deprecated = true];
optional bool deprecated = 23 [default = false];
optional bool java_string_check_utf8 = 27 [default = false];
optional bool cc_enable_arenas = 31 [default = true];
optional string objc_class_prefix = 36;
optional string csharp_namespace = 37;
optional string swift_prefix = 39;
optional string php_class_prefix = 40;
optional string php_namespace = 41;
optional string php_metadata_namespace = 44;
optional string ruby_package = 45;
optional FeatureSet features = 50;
repeated UninterpretedOption uninterpreted_option = 999;
enum OptimizeMode {
SPEED = 1;
CODE_SIZE = 2;
LITE_RUNTIME = 3;
}
extensions 1000 to max;
reserved 38, 42;
reserved "php_generic_services";
}
message MessageOptions {
optional bool message_set_wire_format = 1 [default = false];
optional bool no_standard_descriptor_accessor = 2 [default = false];
optional bool deprecated = 3 [default = false];
optional bool map_entry = 7;
optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true];
optional FeatureSet features = 12;
repeated UninterpretedOption uninterpreted_option = 999;
extensions 1000 to max;
reserved 4, 5, 6, 8, 9;
}
message UninterpretedOption {
repeated NamePart name = 2;
optional string identifier_value = 3;
optional uint64 positive_int_value = 4;
optional int64 negative_int_value = 5;
optional double double_value = 6;
optional bytes string_value = 7;
optional string aggregate_value = 8;
message NamePart {
required string name_part = 1;
required bool is_extension = 2;
}
}
enum Edition {
EDITION_UNKNOWN = 0;
EDITION_1_TEST_ONLY = 1;
EDITION_2_TEST_ONLY = 2;
EDITION_LEGACY = 900;
EDITION_PROTO2 = 998;
EDITION_PROTO3 = 999;
EDITION_2023 = 1000;
EDITION_2024 = 1001;
EDITION_99997_TEST_ONLY = 99997;
EDITION_99998_TEST_ONLY = 99998;
EDITION_99999_TEST_ONLY = 99999;
EDITION_MAX = 2147483647;
}
-- test.proto --
syntax = "proto3";
package test;
import "a.proto";
message EnumA {
a.A.AEnum a = 1;
}
Loading