14
14
15
15
package com .google .api .generator .gapic .protoparser ;
16
16
17
+ import com .google .api .ClientLibrarySettings ;
17
18
import com .google .api .ClientProto ;
18
19
import com .google .api .DocumentationRule ;
19
20
import com .google .api .FieldBehavior ;
84
85
import java .util .Optional ;
85
86
import java .util .Set ;
86
87
import java .util .function .Function ;
88
+ import java .util .logging .Level ;
87
89
import java .util .logging .Logger ;
88
90
import java .util .stream .Collectors ;
89
91
import java .util .stream .IntStream ;
@@ -160,11 +162,11 @@ public static GapicContext parse(CodeGeneratorRequest request) {
160
162
messages = updateResourceNamesInMessages (messages , resourceNames .values ());
161
163
162
164
// Contains only resource names that are actually used. Usage refers to the presence of a
163
- // request message's field in an RPC's method_signature annotation. That is, resource name
164
- // definitions
165
- // or references that are simply defined, but not used in such a manner, will not have
166
- // corresponding Java helper
167
- // classes generated.
165
+ // request message's field in an RPC's method_signature annotation. That is, resource name
166
+ // definitions or references that are simply defined, but not used in such a manner,
167
+ // will not have corresponding Java helper classes generated.
168
+ // If selective api generation is configured via service yaml, Java helper classes are only
169
+ // generated if resource names are actually used by methods selected to generate .
168
170
Set <ResourceName > outputArgResourceNames = new HashSet <>();
169
171
List <Service > mixinServices = new ArrayList <>();
170
172
Transport transport = Transport .parse (transportOpt .orElse (Transport .GRPC .toString ()));
@@ -425,6 +427,71 @@ public static List<Service> parseService(
425
427
Transport .GRPC );
426
428
}
427
429
430
+ static boolean shouldIncludeMethodInGeneration (
431
+ MethodDescriptor method ,
432
+ Optional <com .google .api .Service > serviceYamlProtoOpt ,
433
+ String protoPackage ) {
434
+ // default to include all when no service yaml or no library setting section.
435
+ if (!serviceYamlProtoOpt .isPresent ()
436
+ || serviceYamlProtoOpt .get ().getPublishing ().getLibrarySettingsCount () == 0 ) {
437
+ return true ;
438
+ }
439
+ List <ClientLibrarySettings > librarySettingsList =
440
+ serviceYamlProtoOpt .get ().getPublishing ().getLibrarySettingsList ();
441
+ // Validate for logging purpose, this should be validated upstream.
442
+ // If library_settings.version does not match with proto package name
443
+ // Give warnings and disregard this config. default to include all.
444
+ if (!librarySettingsList .get (0 ).getVersion ().isEmpty ()
445
+ && !protoPackage .equals (librarySettingsList .get (0 ).getVersion ())) {
446
+ if (LOGGER .isLoggable (Level .WARNING )) {
447
+ LOGGER .warning (
448
+ String .format (
449
+ "Service yaml config is misconfigured. Version in "
450
+ + "publishing.library_settings (%s) does not match proto package (%s)."
451
+ + "Disregarding selective generation settings." ,
452
+ librarySettingsList .get (0 ).getVersion (), protoPackage ));
453
+ }
454
+ return true ;
455
+ }
456
+ // librarySettingsList is technically a list, but is processed upstream and
457
+ // only leave with 1 element. Otherwise, it is a misconfiguration and
458
+ // should be caught upstream.
459
+ List <String > includeMethodsList =
460
+ librarySettingsList
461
+ .get (0 )
462
+ .getJavaSettings ()
463
+ .getCommon ()
464
+ .getSelectiveGapicGeneration ()
465
+ .getMethodsList ();
466
+ // default to include all when nothing specified, this could be no java section
467
+ // specified in library setting, or the method list is empty
468
+ if (includeMethodsList .isEmpty ()) {
469
+ return true ;
470
+ }
471
+
472
+ return includeMethodsList .contains (method .getFullName ());
473
+ }
474
+
475
+ private static boolean isEmptyService (
476
+ ServiceDescriptor serviceDescriptor ,
477
+ Optional <com .google .api .Service > serviceYamlProtoOpt ,
478
+ String protoPackage ) {
479
+ List <MethodDescriptor > methodsList = serviceDescriptor .getMethods ();
480
+ List <MethodDescriptor > methodListSelected =
481
+ methodsList .stream ()
482
+ .filter (
483
+ method ->
484
+ shouldIncludeMethodInGeneration (method , serviceYamlProtoOpt , protoPackage ))
485
+ .collect (Collectors .toList ());
486
+ if (methodListSelected .isEmpty ()) {
487
+ LOGGER .log (
488
+ Level .WARNING ,
489
+ "Service {0} has no RPC methods and will not be generated" ,
490
+ serviceDescriptor .getName ());
491
+ }
492
+ return methodListSelected .isEmpty ();
493
+ }
494
+
428
495
public static List <Service > parseService (
429
496
FileDescriptor fileDescriptor ,
430
497
Map <String , Message > messageTypes ,
@@ -433,19 +500,11 @@ public static List<Service> parseService(
433
500
Optional <GapicServiceConfig > serviceConfigOpt ,
434
501
Set <ResourceName > outputArgResourceNames ,
435
502
Transport transport ) {
436
-
503
+ String protoPackage = fileDescriptor . getPackage ();
437
504
return fileDescriptor .getServices ().stream ()
438
505
.filter (
439
- serviceDescriptor -> {
440
- List <MethodDescriptor > methodsList = serviceDescriptor .getMethods ();
441
- if (methodsList .isEmpty ()) {
442
- LOGGER .warning (
443
- String .format (
444
- "Service %s has no RPC methods and will not be generated" ,
445
- serviceDescriptor .getName ()));
446
- }
447
- return !methodsList .isEmpty ();
448
- })
506
+ serviceDescriptor ->
507
+ !isEmptyService (serviceDescriptor , serviceYamlProtoOpt , protoPackage ))
449
508
.map (
450
509
s -> {
451
510
// Workaround for a missing default_host and oauth_scopes annotation from a service
@@ -498,6 +557,8 @@ public static List<Service> parseService(
498
557
String pakkage = TypeParser .getPackage (fileDescriptor );
499
558
String originalJavaPackage = pakkage ;
500
559
// Override Java package with that specified in gapic.yaml.
560
+ // this override is deprecated and legacy support only
561
+ // see go/client-user-guide#configure-long-running-operation-polling-timeouts-optional
501
562
if (serviceConfigOpt .isPresent ()
502
563
&& serviceConfigOpt .get ().getLanguageSettingsOpt ().isPresent ()) {
503
564
GapicLanguageSettings languageSettings =
@@ -518,6 +579,7 @@ public static List<Service> parseService(
518
579
.setMethods (
519
580
parseMethods (
520
581
s ,
582
+ protoPackage ,
521
583
pakkage ,
522
584
messageTypes ,
523
585
resourceNames ,
@@ -709,6 +771,7 @@ public static Map<String, ResourceName> parseResourceNames(
709
771
@ VisibleForTesting
710
772
static List <Method > parseMethods (
711
773
ServiceDescriptor serviceDescriptor ,
774
+ String protoPackage ,
712
775
String servicePackage ,
713
776
Map <String , Message > messageTypes ,
714
777
Map <String , ResourceName > resourceNames ,
@@ -721,8 +784,10 @@ static List<Method> parseMethods(
721
784
// Parse the serviceYaml for autopopulated methods and fields once and put into a map
722
785
Map <String , List <String >> autoPopulatedMethodsWithFields =
723
786
parseAutoPopulatedMethodsAndFields (serviceYamlProtoOpt );
724
-
725
787
for (MethodDescriptor protoMethod : serviceDescriptor .getMethods ()) {
788
+ if (!shouldIncludeMethodInGeneration (protoMethod , serviceYamlProtoOpt , protoPackage )) {
789
+ continue ;
790
+ }
726
791
// Parse the method.
727
792
TypeNode inputType = TypeParser .parseType (protoMethod .getInputType ());
728
793
Method .Builder methodBuilder = Method .builder ();
0 commit comments