Skip to content

Commit 42f8b2b

Browse files
authored
Fix type filter import filtering for options (#3727)
1 parent 7fbca23 commit 42f8b2b

File tree

9 files changed

+649
-1
lines changed

9 files changed

+649
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

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

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

private/bufpkg/bufimage/bufimageutil/bufimageutil.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ func (t *transitiveClosure) addElement(
475475
}
476476
oneofFieldCounts[index]++
477477
}
478-
if err := t.exploreCustomOptions(field, referrerFile, imageIndex, opts); err != nil {
478+
if err := t.exploreCustomOptions(field, descriptorInfo.file.Path(), imageIndex, opts); err != nil {
479479
return err
480480
}
481481
}

private/bufpkg/bufimage/bufimageutil/bufimageutil_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,19 @@ func TestConsecutiveFilters(t *testing.T) {
483483
})
484484
}
485485

486+
func TestDependencies(t *testing.T) {
487+
t.Parallel()
488+
// Test referred file for options of imported types.
489+
t.Run("FieldA", func(t *testing.T) {
490+
t.Parallel()
491+
runDiffTest(t, "testdata/deps", "test.FieldA.txtar", WithIncludeTypes("test.FieldA"))
492+
})
493+
t.Run("EnumA", func(t *testing.T) {
494+
t.Parallel()
495+
runDiffTest(t, "testdata/deps", "test.EnumA.txtar", WithIncludeTypes("test.EnumA"))
496+
})
497+
}
498+
486499
func getImage(ctx context.Context, logger *slog.Logger, testdataDir string, options ...bufimage.BuildImageOption) (storage.ReadWriteBucket, bufimage.Image, error) {
487500
bucket, err := storageos.NewProvider().NewReadWriteBucket(testdataDir)
488501
if err != nil {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
syntax = "proto3";
2+
package a;
3+
4+
import "b.proto";
5+
6+
option (b.B.file_c).c = "c";
7+
8+
message A {
9+
option (b.message_c).c = "c";
10+
11+
string a = 1 [(b.field_c).c = "c"];
12+
13+
oneof oneof_a {
14+
option (b.oneof_c).c = "c";
15+
16+
string foo = 2;
17+
string bar = 3;
18+
}
19+
20+
enum AEnum {
21+
option (b.enum_c).c = "c";
22+
23+
FOO_ENUM_A = 0;
24+
FOO_ENUM_B = 1 [(b.enum_value_c).c = "c"];
25+
}
26+
}
27+
28+
service AService {
29+
option (b.service_c).c = "c";
30+
31+
rpc Method(A) returns (A) {
32+
option (b.method_c).c = "c";
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
syntax = "proto3";
2+
package b;
3+
4+
import "c.proto";
5+
import "google/protobuf/descriptor.proto";
6+
7+
message B {
8+
extend google.protobuf.FileOptions {
9+
optional c.C file_c = 50000;
10+
}
11+
string b = 1;
12+
}
13+
14+
extend google.protobuf.MessageOptions {
15+
optional c.C message_c = 50000;
16+
}
17+
extend google.protobuf.FieldOptions {
18+
optional c.C field_c = 50000;
19+
}
20+
extend google.protobuf.OneofOptions {
21+
optional c.C oneof_c = 50000;
22+
}
23+
extend google.protobuf.EnumOptions {
24+
optional c.C enum_c = 50000;
25+
}
26+
extend google.protobuf.EnumValueOptions {
27+
optional c.C enum_value_c = 50000;
28+
}
29+
extend google.protobuf.ServiceOptions {
30+
optional c.C service_c = 50000;
31+
}
32+
extend google.protobuf.MethodOptions {
33+
optional c.C method_c = 50000;
34+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
syntax = "proto3";
2+
package c;
3+
4+
message C {
5+
string c = 1;
6+
}
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
-- a.proto --
2+
syntax = "proto3";
3+
package a;
4+
import "b.proto";
5+
option (b.B.file_c) = { c: "c" };
6+
message A {
7+
option (b.message_c) = { c: "c" };
8+
enum AEnum {
9+
option (b.enum_c) = { c: "c" };
10+
FOO_ENUM_A = 0;
11+
FOO_ENUM_B = 1 [(b.enum_value_c) = { c: "c" }];
12+
}
13+
}
14+
-- b.proto --
15+
syntax = "proto3";
16+
package b;
17+
import "c.proto";
18+
import "google/protobuf/descriptor.proto";
19+
message B {
20+
extend google.protobuf.FileOptions {
21+
c.C file_c = 50000;
22+
}
23+
}
24+
extend google.protobuf.EnumOptions {
25+
c.C enum_c = 50000;
26+
}
27+
extend google.protobuf.EnumValueOptions {
28+
c.C enum_value_c = 50000;
29+
}
30+
extend google.protobuf.MessageOptions {
31+
c.C message_c = 50000;
32+
}
33+
-- c.proto --
34+
syntax = "proto3";
35+
package c;
36+
message C {
37+
string c = 1;
38+
}
39+
-- google/protobuf/descriptor.proto --
40+
syntax = "proto2";
41+
package google.protobuf;
42+
option cc_enable_arenas = true;
43+
option csharp_namespace = "Google.Protobuf.Reflection";
44+
option go_package = "google.golang.org/protobuf/types/descriptorpb";
45+
option java_outer_classname = "DescriptorProtos";
46+
option java_package = "com.google.protobuf";
47+
option objc_class_prefix = "GPB";
48+
option optimize_for = SPEED;
49+
message EnumOptions {
50+
optional bool allow_alias = 2;
51+
optional bool deprecated = 3 [default = false];
52+
optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true];
53+
optional FeatureSet features = 7;
54+
repeated UninterpretedOption uninterpreted_option = 999;
55+
extensions 1000 to max;
56+
reserved 5;
57+
}
58+
message EnumValueOptions {
59+
optional bool deprecated = 1 [default = false];
60+
optional FeatureSet features = 2;
61+
optional bool debug_redact = 3 [default = false];
62+
optional FieldOptions.FeatureSupport feature_support = 4;
63+
repeated UninterpretedOption uninterpreted_option = 999;
64+
extensions 1000 to max;
65+
}
66+
message FeatureSet {
67+
optional FieldPresence field_presence = 1 [
68+
edition_defaults = { value: "EXPLICIT", edition: EDITION_LEGACY },
69+
edition_defaults = { value: "IMPLICIT", edition: EDITION_PROTO3 },
70+
edition_defaults = { value: "EXPLICIT", edition: EDITION_2023 },
71+
feature_support = { edition_introduced: EDITION_2023 },
72+
retention = RETENTION_RUNTIME,
73+
targets = TARGET_TYPE_FIELD,
74+
targets = TARGET_TYPE_FILE
75+
];
76+
optional EnumType enum_type = 2 [
77+
edition_defaults = { value: "CLOSED", edition: EDITION_LEGACY },
78+
edition_defaults = { value: "OPEN", edition: EDITION_PROTO3 },
79+
feature_support = { edition_introduced: EDITION_2023 },
80+
retention = RETENTION_RUNTIME,
81+
targets = TARGET_TYPE_ENUM,
82+
targets = TARGET_TYPE_FILE
83+
];
84+
optional RepeatedFieldEncoding repeated_field_encoding = 3 [
85+
edition_defaults = { value: "EXPANDED", edition: EDITION_LEGACY },
86+
edition_defaults = { value: "PACKED", edition: EDITION_PROTO3 },
87+
feature_support = { edition_introduced: EDITION_2023 },
88+
retention = RETENTION_RUNTIME,
89+
targets = TARGET_TYPE_FIELD,
90+
targets = TARGET_TYPE_FILE
91+
];
92+
optional Utf8Validation utf8_validation = 4 [
93+
edition_defaults = { value: "NONE", edition: EDITION_LEGACY },
94+
edition_defaults = { value: "VERIFY", edition: EDITION_PROTO3 },
95+
feature_support = { edition_introduced: EDITION_2023 },
96+
retention = RETENTION_RUNTIME,
97+
targets = TARGET_TYPE_FIELD,
98+
targets = TARGET_TYPE_FILE
99+
];
100+
optional MessageEncoding message_encoding = 5 [
101+
edition_defaults = { value: "LENGTH_PREFIXED", edition: EDITION_LEGACY },
102+
feature_support = { edition_introduced: EDITION_2023 },
103+
retention = RETENTION_RUNTIME,
104+
targets = TARGET_TYPE_FIELD,
105+
targets = TARGET_TYPE_FILE
106+
];
107+
optional JsonFormat json_format = 6 [
108+
edition_defaults = { value: "LEGACY_BEST_EFFORT", edition: EDITION_LEGACY },
109+
edition_defaults = { value: "ALLOW", edition: EDITION_PROTO3 },
110+
feature_support = { edition_introduced: EDITION_2023 },
111+
retention = RETENTION_RUNTIME,
112+
targets = TARGET_TYPE_MESSAGE,
113+
targets = TARGET_TYPE_ENUM,
114+
targets = TARGET_TYPE_FILE
115+
];
116+
enum EnumType {
117+
ENUM_TYPE_UNKNOWN = 0;
118+
OPEN = 1;
119+
CLOSED = 2;
120+
}
121+
enum FieldPresence {
122+
FIELD_PRESENCE_UNKNOWN = 0;
123+
EXPLICIT = 1;
124+
IMPLICIT = 2;
125+
LEGACY_REQUIRED = 3;
126+
}
127+
enum JsonFormat {
128+
JSON_FORMAT_UNKNOWN = 0;
129+
ALLOW = 1;
130+
LEGACY_BEST_EFFORT = 2;
131+
}
132+
enum MessageEncoding {
133+
MESSAGE_ENCODING_UNKNOWN = 0;
134+
LENGTH_PREFIXED = 1;
135+
DELIMITED = 2;
136+
}
137+
enum RepeatedFieldEncoding {
138+
REPEATED_FIELD_ENCODING_UNKNOWN = 0;
139+
PACKED = 1;
140+
EXPANDED = 2;
141+
}
142+
enum Utf8Validation {
143+
UTF8_VALIDATION_UNKNOWN = 0;
144+
VERIFY = 2;
145+
NONE = 3;
146+
reserved 1;
147+
}
148+
extensions 1000 to 9994 [
149+
declaration = {
150+
number: 1000,
151+
full_name: ".pb.cpp",
152+
type: ".pb.CppFeatures"
153+
},
154+
declaration = {
155+
number: 1001,
156+
full_name: ".pb.java",
157+
type: ".pb.JavaFeatures"
158+
},
159+
declaration = {
160+
number: 1002,
161+
full_name: ".pb.go",
162+
type: ".pb.GoFeatures"
163+
},
164+
declaration = {
165+
number: 9990,
166+
full_name: ".pb.proto1",
167+
type: ".pb.Proto1Features"
168+
}
169+
];
170+
extensions 9995 to 9999, 10000;
171+
reserved 999;
172+
}
173+
message FieldOptions {
174+
message FeatureSupport {
175+
optional Edition edition_introduced = 1;
176+
optional Edition edition_deprecated = 2;
177+
optional string deprecation_warning = 3;
178+
optional Edition edition_removed = 4;
179+
}
180+
}
181+
message FileOptions {
182+
optional string java_package = 1;
183+
optional string java_outer_classname = 8;
184+
optional OptimizeMode optimize_for = 9 [default = SPEED];
185+
optional bool java_multiple_files = 10 [default = false];
186+
optional string go_package = 11;
187+
optional bool cc_generic_services = 16 [default = false];
188+
optional bool java_generic_services = 17 [default = false];
189+
optional bool py_generic_services = 18 [default = false];
190+
optional bool java_generate_equals_and_hash = 20 [deprecated = true];
191+
optional bool deprecated = 23 [default = false];
192+
optional bool java_string_check_utf8 = 27 [default = false];
193+
optional bool cc_enable_arenas = 31 [default = true];
194+
optional string objc_class_prefix = 36;
195+
optional string csharp_namespace = 37;
196+
optional string swift_prefix = 39;
197+
optional string php_class_prefix = 40;
198+
optional string php_namespace = 41;
199+
optional string php_metadata_namespace = 44;
200+
optional string ruby_package = 45;
201+
optional FeatureSet features = 50;
202+
repeated UninterpretedOption uninterpreted_option = 999;
203+
enum OptimizeMode {
204+
SPEED = 1;
205+
CODE_SIZE = 2;
206+
LITE_RUNTIME = 3;
207+
}
208+
extensions 1000 to max;
209+
reserved 38, 42;
210+
reserved "php_generic_services";
211+
}
212+
message MessageOptions {
213+
optional bool message_set_wire_format = 1 [default = false];
214+
optional bool no_standard_descriptor_accessor = 2 [default = false];
215+
optional bool deprecated = 3 [default = false];
216+
optional bool map_entry = 7;
217+
optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true];
218+
optional FeatureSet features = 12;
219+
repeated UninterpretedOption uninterpreted_option = 999;
220+
extensions 1000 to max;
221+
reserved 4, 5, 6, 8, 9;
222+
}
223+
message UninterpretedOption {
224+
repeated NamePart name = 2;
225+
optional string identifier_value = 3;
226+
optional uint64 positive_int_value = 4;
227+
optional int64 negative_int_value = 5;
228+
optional double double_value = 6;
229+
optional bytes string_value = 7;
230+
optional string aggregate_value = 8;
231+
message NamePart {
232+
required string name_part = 1;
233+
required bool is_extension = 2;
234+
}
235+
}
236+
enum Edition {
237+
EDITION_UNKNOWN = 0;
238+
EDITION_1_TEST_ONLY = 1;
239+
EDITION_2_TEST_ONLY = 2;
240+
EDITION_LEGACY = 900;
241+
EDITION_PROTO2 = 998;
242+
EDITION_PROTO3 = 999;
243+
EDITION_2023 = 1000;
244+
EDITION_2024 = 1001;
245+
EDITION_99997_TEST_ONLY = 99997;
246+
EDITION_99998_TEST_ONLY = 99998;
247+
EDITION_99999_TEST_ONLY = 99999;
248+
EDITION_MAX = 2147483647;
249+
}
250+
-- test.proto --
251+
syntax = "proto3";
252+
package test;
253+
import "a.proto";
254+
message EnumA {
255+
a.A.AEnum a = 1;
256+
}

0 commit comments

Comments
 (0)