17
17
import com .google .auto .value .AutoValue ;
18
18
import com .google .common .collect .ImmutableList ;
19
19
import com .google .devtools .build .lib .analysis .FilesToRunProvider ;
20
+ import com .google .devtools .build .lib .analysis .RuleContext ;
20
21
import com .google .devtools .build .lib .analysis .TransitiveInfoCollection ;
21
- import com .google .devtools .build .lib .packages .BuiltinProvider ;
22
- import com .google .devtools .build .lib .packages .NativeInfo ;
22
+ import com .google .devtools .build .lib .cmdline .Label ;
23
+ import com .google .devtools .build .lib .collect .nestedset .Depset ;
24
+ import com .google .devtools .build .lib .collect .nestedset .Depset .ElementType ;
25
+ import com .google .devtools .build .lib .collect .nestedset .NestedSetBuilder ;
26
+ import com .google .devtools .build .lib .packages .StarlarkInfo ;
27
+ import com .google .devtools .build .lib .packages .StarlarkProvider ;
28
+ import com .google .devtools .build .lib .packages .StarlarkProviderIdentifier ;
29
+ import java .util .LinkedHashMap ;
30
+ import java .util .Map ;
23
31
import javax .annotation .Nullable ;
24
- import net .starlark .java .annot .StarlarkBuiltin ;
25
- import net .starlark .java .annot .StarlarkMethod ;
32
+ import net .starlark .java .eval .EvalException ;
33
+ import net .starlark .java .eval .NoneType ;
34
+ import net .starlark .java .eval .Starlark ;
26
35
import net .starlark .java .eval .StarlarkList ;
36
+ import net .starlark .java .syntax .Location ;
27
37
28
38
// Note: AutoValue v1.4-rc1 has AutoValue.CopyAnnotations which makes it work with Starlark. No need
29
39
// to un-AutoValue this class to expose it to Starlark.
32
42
* rules.
33
43
*/
34
44
@ AutoValue
35
- public abstract class ProtoLangToolchainProvider extends NativeInfo {
45
+ public abstract class ProtoLangToolchainProvider {
36
46
public static final String PROVIDER_NAME = "ProtoLangToolchainInfo" ;
37
- public static final Provider PROVIDER = new Provider ();
47
+ public static final StarlarkProvider .Key starlarkProtoLangToolchainKey =
48
+ new StarlarkProvider .Key (
49
+ Label .parseAbsoluteUnchecked ("@_builtins//:common/proto/providers.bzl" ), PROVIDER_NAME );
50
+ public static final StarlarkProviderIdentifier PROVIDER_ID =
51
+ StarlarkProviderIdentifier .forKey (starlarkProtoLangToolchainKey );
38
52
39
- /** Provider class for {@link ProtoLangToolchainProvider} objects. */
40
- @ StarlarkBuiltin (name = "Provider" , documented = false , doc = "" )
41
- public static class Provider extends BuiltinProvider <ProtoLangToolchainProvider > {
42
- public Provider () {
43
- super (PROVIDER_NAME , ProtoLangToolchainProvider .class );
44
- }
45
- }
46
-
47
- @ Override
48
- public Provider getProvider () {
49
- return PROVIDER ;
50
- }
51
-
52
- @ StarlarkMethod (
53
- name = "out_replacement_format_flag" ,
54
- doc = "Format string used when passing output to the plugin used by proto compiler." ,
55
- structField = true )
53
+ // Format string used when passing output to the plugin used by proto compiler.
56
54
public abstract String outReplacementFormatFlag ();
57
55
58
- @ StarlarkMethod (
59
- name = "plugin_format_flag" ,
60
- doc = "Format string used when passing plugin to proto compiler." ,
61
- structField = true ,
62
- allowReturnNones = true )
56
+ // Format string used when passing plugin to proto compiler.
63
57
@ Nullable
64
58
public abstract String pluginFormatFlag ();
65
59
66
- @ StarlarkMethod (
67
- name = "plugin" ,
68
- doc = "Proto compiler plugin." ,
69
- structField = true ,
70
- allowReturnNones = true )
60
+ // Proto compiler plugin.
71
61
@ Nullable
72
62
public abstract FilesToRunProvider pluginExecutable ();
73
63
@@ -78,38 +68,26 @@ public Provider getProvider() {
78
68
* Returns a list of {@link ProtoSource}s that are already provided by the protobuf runtime (i.e.
79
69
* for which {@code <lang>_proto_library} should not generate bindings.
80
70
*/
81
- @ StarlarkMethod (
82
- name = "provided_proto_sources" ,
83
- doc = "Proto sources provided by the toolchain." ,
84
- structField = true )
71
+ // Proto sources provided by the toolchain.
85
72
public abstract ImmutableList <ProtoSource > providedProtoSources ();
86
73
87
- @ StarlarkMethod ( name = "proto_compiler" , doc = " Proto compiler." , structField = true )
74
+ // Proto compiler.
88
75
public abstract FilesToRunProvider protoc ();
89
76
90
- @ StarlarkMethod (
91
- name = "protoc_opts" ,
92
- doc = "Options to pass to proto compiler." ,
93
- structField = true )
77
+ // Options to pass to proto compiler.
94
78
public StarlarkList <String > protocOptsForStarlark () {
95
79
return StarlarkList .immutableCopyOf (protocOpts ());
96
80
}
97
81
98
82
public abstract ImmutableList <String > protocOpts ();
99
83
100
- @ StarlarkMethod (
101
- name = "progress_message" ,
102
- doc = "Progress message to set on the proto compiler action." ,
103
- structField = true )
84
+ // Progress message to set on the proto compiler action.
104
85
public abstract String progressMessage ();
105
86
106
- @ StarlarkMethod (
107
- name = "mnemonic" ,
108
- doc = "Mnemonic to set on the proto compiler action." ,
109
- structField = true )
87
+ // Mnemonic to set on the proto compiler action.
110
88
public abstract String mnemonic ();
111
89
112
- public static ProtoLangToolchainProvider create (
90
+ public static StarlarkInfo create (
113
91
String outReplacementFormatFlag ,
114
92
String pluginFormatFlag ,
115
93
FilesToRunProvider pluginExecutable ,
@@ -119,15 +97,93 @@ public static ProtoLangToolchainProvider create(
119
97
ImmutableList <String > protocOpts ,
120
98
String progressMessage ,
121
99
String mnemonic ) {
122
- return new AutoValue_ProtoLangToolchainProvider (
123
- outReplacementFormatFlag ,
124
- pluginFormatFlag ,
125
- pluginExecutable ,
126
- runtime ,
127
- providedProtoSources ,
128
- protoc ,
129
- protocOpts ,
130
- progressMessage ,
131
- mnemonic );
100
+
101
+ NestedSetBuilder <ProtoSource > providedProtoSourcesSet = NestedSetBuilder .stableOrder ();
102
+ providedProtoSources .forEach (providedProtoSourcesSet ::add );
103
+ NestedSetBuilder <String > protocOptsSet = NestedSetBuilder .stableOrder ();
104
+ protocOpts .forEach (protocOptsSet ::add );
105
+
106
+ Map <String , Object > m = new LinkedHashMap <>();
107
+ m .put ("plugin" , pluginExecutable == null ? Starlark .NONE : pluginExecutable );
108
+ m .put ("plugin_format_flag" , pluginFormatFlag );
109
+ m .put ("proto_compiler" , protoc == null ? Starlark .NONE : protoc );
110
+ m .put (
111
+ "provided_proto_sources" ,
112
+ Depset .of (ElementType .of (ProtoSource .class ), providedProtoSourcesSet .build ()));
113
+ m .put ("protoc_opts" , Depset .of (ElementType .of (ProtoSource .class ), protocOptsSet .build ()));
114
+ m .put ("out_replacement_format_flag" , outReplacementFormatFlag );
115
+ m .put ("progress_message" , progressMessage );
116
+ m .put ("mnemonic" , mnemonic );
117
+ m .put ("plugin" , pluginExecutable == null ? Starlark .NONE : pluginExecutable );
118
+ m .put ("runtime" , runtime == null ? Starlark .NONE : runtime );
119
+
120
+ StarlarkProvider .Builder builder =
121
+ StarlarkProvider .builder (
122
+ Location .fromFileLineColumn (protoc .getExecutable ().getFilename (), 0 , 0 ));
123
+ builder .setExported (starlarkProtoLangToolchainKey );
124
+
125
+ return StarlarkInfo .create (builder .build (), m , Location .BUILTIN );
126
+ }
127
+
128
+ private static ImmutableList <ProtoLangToolchainProvider > getToolchains (
129
+ RuleContext ruleContext , String attributeName ) {
130
+ ImmutableList .Builder <ProtoLangToolchainProvider > result = ImmutableList .builder ();
131
+ for (TransitiveInfoCollection prerequisite : ruleContext .getPrerequisites (attributeName )) {
132
+ ProtoLangToolchainProvider toolchain = get (prerequisite );
133
+ if (toolchain != null ) {
134
+ result .add (toolchain );
135
+ }
136
+ }
137
+ return result .build ();
138
+ }
139
+
140
+ public static ProtoLangToolchainProvider get (RuleContext ruleContext , String attributeName ) {
141
+ return getToolchains (ruleContext , attributeName ).stream ().findFirst ().orElse (null );
142
+ }
143
+
144
+ public static ProtoLangToolchainProvider get (TransitiveInfoCollection prerequisite ) {
145
+ StarlarkInfo provider = (StarlarkInfo ) prerequisite .get (starlarkProtoLangToolchainKey );
146
+ return wrapStarlarkProviderWithNativeProvider (provider );
147
+ }
148
+
149
+ public static StarlarkInfo getStarlarkProvider (RuleContext ruleContext , String attributeName ) {
150
+ for (TransitiveInfoCollection prerequisite : ruleContext .getPrerequisites (attributeName )) {
151
+ StarlarkInfo provider = (StarlarkInfo ) prerequisite .get (starlarkProtoLangToolchainKey );
152
+ if (provider != null ) {
153
+ return provider ;
154
+ }
155
+ }
156
+ return null ;
157
+ }
158
+
159
+ public static StarlarkInfo getStarlarkProvider (TransitiveInfoCollection prerequisite ) {
160
+ return (StarlarkInfo ) prerequisite .get (starlarkProtoLangToolchainKey );
161
+ }
162
+
163
+ @ SuppressWarnings ("unchecked" )
164
+ private static ProtoLangToolchainProvider wrapStarlarkProviderWithNativeProvider (
165
+ StarlarkInfo provider ) {
166
+ if (provider != null ) {
167
+ try {
168
+ return new AutoValue_ProtoLangToolchainProvider (
169
+ provider .getValue ("out_replacement_format_flag" , String .class ),
170
+ provider .getValue ("plugin_format_flag" , String .class ),
171
+ provider .getValue ("plugin" ) instanceof NoneType
172
+ ? null
173
+ : provider .getValue ("plugin" , FilesToRunProvider .class ),
174
+ provider .getValue ("runtime" ) instanceof NoneType
175
+ ? null
176
+ : provider .getValue ("runtime" , TransitiveInfoCollection .class ),
177
+ ImmutableList .copyOf (
178
+ (StarlarkList <ProtoSource >) provider .getValue ("provided_proto_sources" )),
179
+ provider .getValue ("proto_compiler" , FilesToRunProvider .class ),
180
+ ImmutableList .copyOf ((StarlarkList <String >) provider .getValue ("protoc_opts" )),
181
+ provider .getValue ("progress_message" , String .class ),
182
+ provider .getValue ("mnemonic" , String .class ));
183
+ } catch (EvalException e ) {
184
+ return null ;
185
+ }
186
+ }
187
+ return null ;
132
188
}
133
189
}
0 commit comments