Skip to content

feat: Selective gapic generation phase II #3730

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

Merged
merged 27 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
595198b
feat: Selective gapic generation phase II
cindy-peng Apr 1, 2025
f5c93db
Add selective gapic yaml files and golden files
cindy-peng Apr 2, 2025
734efa9
add golden test files
cindy-peng Apr 2, 2025
fbb19ea
Revert service client throw comment
cindy-peng Apr 2, 2025
03220b9
Revert integration golden files
cindy-peng Apr 2, 2025
c516814
Merge branch 'main' into cindy/selective-gapic
cindy-peng Apr 2, 2025
55de64f
Merge branch 'main' into cindy/selective-gapic
cindy-peng Apr 3, 2025
27bdc9e
Merge branch 'main' into cindy/selective-gapic
cindy-peng Apr 7, 2025
1f77302
Remove enum from method model
cindy-peng Apr 7, 2025
eb0c6bf
Set default method level to be public
cindy-peng Apr 7, 2025
5a21be7
Fix formatting errors
cindy-peng Apr 7, 2025
5fad1fe
Change isPublic attribute to isInternalApi in method class
cindy-peng Apr 10, 2025
182a517
Merge branch 'main' into cindy/selective-gapic
cindy-peng Apr 10, 2025
221eb8f
Fix linter
cindy-peng Apr 10, 2025
ffd66db
Fix comments from PR review.
cindy-peng Apr 15, 2025
602b910
Merge branch 'main' into cindy/selective-gapic
cindy-peng Apr 15, 2025
a87d3b0
Fix linter.
cindy-peng Apr 15, 2025
cbb7ce5
Add unit tests for stub, stub settings,service settings
cindy-peng Apr 16, 2025
6c30173
Fix Javadoc comment line break before @InternalApi comment
cindy-peng Apr 16, 2025
b481cc7
Change block tag to start with lowercase to resolve formatter issue.
cindy-peng Apr 16, 2025
edafba1
Fix comment to be lowercase @internalApi
cindy-peng Apr 16, 2025
f4c9cf7
Change internalApi javadoc comment to be additional descriptive text.
cindy-peng Apr 17, 2025
385873d
Merge branch 'main' into cindy/selective-gapic
cindy-peng Apr 17, 2025
7c3aeaa
Add common string and unit tests for parser.
cindy-peng Apr 17, 2025
b0553ac
Add common string and unit tests for parser.
cindy-peng Apr 17, 2025
01bc7f7
Change internal use warning message.
cindy-peng Apr 17, 2025
2ece35b
Fix linter formatting.
cindy-peng Apr 17, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public abstract static class Builder {
String throwsType = null;
String throwsDescription = null;
String deprecated = null;
String internalOnly = null;
String returnDescription = null;
List<String> paramsList = new ArrayList<>();
List<String> componentsList = new ArrayList<>();
Expand All @@ -71,6 +72,11 @@ public Builder setDeprecated(String deprecatedText) {
return this;
}

public Builder setInternalOnly(String internalOnlyText) {
internalOnly = internalOnlyText;
return this;
}

public Builder setReturn(String returnText) {
returnDescription = returnText;
return this;
Expand Down Expand Up @@ -136,6 +142,7 @@ public boolean emptyComments() {
return Strings.isNullOrEmpty(throwsType)
&& Strings.isNullOrEmpty(throwsDescription)
&& Strings.isNullOrEmpty(deprecated)
&& Strings.isNullOrEmpty(internalOnly)
&& Strings.isNullOrEmpty(returnDescription)
&& paramsList.isEmpty()
&& componentsList.isEmpty();
Expand All @@ -151,6 +158,9 @@ public JavaDocComment build() {
if (!Strings.isNullOrEmpty(deprecated)) {
componentsList.add(String.format("@deprecated %s", deprecated));
}
if (!Strings.isNullOrEmpty(internalOnly)) {
componentsList.add(String.format("@InternalApi %s", internalOnly));
}
if (!Strings.isNullOrEmpty(returnDescription)) {
componentsList.add(String.format("@return %s", returnDescription));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public class CommentComposer {
static final String DEPRECATED_METHOD_STRING =
"This method is deprecated and will be removed in the next major version update.";

static final String INTERNAL_ONLY_METHOD_STRING =
"This method is internal used only. Please do not use directly.";

public static final CommentStatement APACHE_LICENSE_COMMENT =
CommentStatement.withComment(BlockComment.withComment(APACHE_LICENSE_STRING));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ public static List<CommentStatement> createRpcMethodHeaderComment(
methodJavadocBuilder.setDeprecated(CommentComposer.DEPRECATED_METHOD_STRING);
}

if (method.isInternalApi()) {
methodJavadocBuilder.setInternalOnly(CommentComposer.INTERNAL_ONLY_METHOD_STRING);
}

List<CommentStatement> comments = new ArrayList<>();
comments.add(CommentComposer.AUTO_GENERATED_METHOD_COMMENT);
if (!methodJavadocBuilder.emptyComments()) {
Expand Down Expand Up @@ -345,6 +349,10 @@ public static List<CommentStatement> createRpcCallableMethodHeaderComment(
methodJavadocBuilder.setDeprecated(CommentComposer.DEPRECATED_METHOD_STRING);
}

if (method.isInternalApi()) {
methodJavadocBuilder.setInternalOnly(CommentComposer.INTERNAL_ONLY_METHOD_STRING);
}

return Arrays.asList(
CommentComposer.AUTO_GENERATED_METHOD_COMMENT,
CommentStatement.withComment(methodJavadocBuilder.build()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,22 @@ public CommentStatement getTransportProviderBuilderMethodComment() {
}

public static CommentStatement createCallSettingsGetterComment(
String javaMethodName, boolean isMethodDeprecated) {
String methodComment = String.format(CALL_SETTINGS_METHOD_DOC_PATTERN, javaMethodName);
return isMethodDeprecated
? toDeprecatedSimpleComment(methodComment)
: toSimpleComment(methodComment);
String javaMethodName, boolean isMethodDeprecated, boolean isMethodInternal) {
return toDeprecatedInternalSimpleComment(
String.format(CALL_SETTINGS_METHOD_DOC_PATTERN, javaMethodName),
isMethodDeprecated,
isMethodInternal);
}

public static CommentStatement createBuilderClassComment(String outerClassName) {
return toSimpleComment(String.format(BUILDER_CLASS_DOC_PATTERN, outerClassName));
}

public static CommentStatement createCallSettingsBuilderGetterComment(
String javaMethodName, boolean isMethodDeprecated) {
String javaMethodName, boolean isMethodDeprecated, boolean isMethodInternal) {
String methodComment = String.format(CALL_SETTINGS_BUILDER_METHOD_DOC_PATTERN, javaMethodName);
return isMethodDeprecated
? toDeprecatedSimpleComment(methodComment)
return isMethodDeprecated || isMethodInternal
? toDeprecatedInternalSimpleComment(methodComment, isMethodDeprecated, isMethodInternal)
: toSimpleComment(methodComment);
}

Expand Down Expand Up @@ -205,11 +205,17 @@ private static CommentStatement toSimpleComment(String comment) {
return CommentStatement.withComment(JavaDocComment.withComment(comment));
}

private static CommentStatement toDeprecatedSimpleComment(String comment) {
return CommentStatement.withComment(
JavaDocComment.builder()
.addComment(comment)
.setDeprecated(CommentComposer.DEPRECATED_METHOD_STRING)
.build());
private static CommentStatement toDeprecatedInternalSimpleComment(
String comment, boolean isDeprecated, boolean isInternal) {
JavaDocComment.Builder docBuilder = JavaDocComment.builder().addComment(comment);
docBuilder =
isDeprecated
? docBuilder.setDeprecated(CommentComposer.DEPRECATED_METHOD_STRING)
: docBuilder;
docBuilder =
isInternal
? docBuilder.setInternalOnly(CommentComposer.INTERNAL_ONLY_METHOD_STRING)
: docBuilder;
return CommentStatement.withComment(docBuilder.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.gax.core.BackgroundResource;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.api.gax.paging.AbstractFixedSizeCollection;
Expand Down Expand Up @@ -107,6 +108,8 @@ public abstract class AbstractServiceClientClassComposer implements ClassCompose
private static final String CALLABLE_NAME_PATTERN = "%sCallable";
private static final String PAGED_CALLABLE_NAME_PATTERN = "%sPagedCallable";
private static final String OPERATION_CALLABLE_NAME_PATTERN = "%sOperationCallable";
private static final String INTERNAL_API_WARNING =
"Internal API. This API is not intended for public consumption.";

private static final Reference LIST_REFERENCE = ConcreteReference.withClazz(List.class);
private static final Reference MAP_REFERENCE = ConcreteReference.withClazz(Map.class);
Expand Down Expand Up @@ -136,7 +139,6 @@ public GapicClass generate(GapicContext context, Service service) {
GapicClass.Kind kind = Kind.MAIN;
String pakkage = service.pakkage();
boolean hasLroClient = service.hasStandardLroMethods();

List<Sample> samples = new ArrayList<>();
Map<String, List<String>> grpcRpcsToJavaMethodNames = new HashMap<>();
Map<String, List<String>> methodVariantsForClientHeader = new HashMap<>();
Expand Down Expand Up @@ -802,11 +804,18 @@ private static List<MethodDefinition> createMethodVariants(
methodVariantBuilder.setReturnType(methodOutputType).setReturnExpr(rpcInvocationExpr);
}

List<AnnotationNode> annotations = new ArrayList<>();
if (method.isDeprecated()) {
methodVariantBuilder =
methodVariantBuilder.setAnnotations(
Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED)));
annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
}

if (method.isInternalApi()) {
annotations.add(
AnnotationNode.withTypeAndDescription(
typeStore.get("InternalApi"), INTERNAL_API_WARNING));
}

methodVariantBuilder = methodVariantBuilder.setAnnotations(annotations);
methodVariantBuilder = methodVariantBuilder.setBody(statements);
javaMethods.add(methodVariantBuilder.build());
}
Expand Down Expand Up @@ -889,6 +898,12 @@ private static MethodDefinition createMethodDefaultMethod(
annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
}

if (method.isInternalApi()) {
annotations.add(
AnnotationNode.withTypeAndDescription(
typeStore.get("InternalApi"), INTERNAL_API_WARNING));
}

if (isProtoEmptyType(methodOutputType)) {
methodBuilder =
methodBuilder
Expand Down Expand Up @@ -1039,11 +1054,17 @@ private static MethodDefinition createCallableMethod(
}

MethodDefinition.Builder methodDefBuilder = MethodDefinition.builder();
List<AnnotationNode> annotations = new ArrayList<>();
if (method.isDeprecated()) {
methodDefBuilder =
methodDefBuilder.setAnnotations(
Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED)));
annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
}
if (method.isInternalApi()) {
annotations.add(
AnnotationNode.withTypeAndDescription(
typeStore.get("InternalApi"), INTERNAL_API_WARNING));
}

methodDefBuilder = methodDefBuilder.setAnnotations(annotations);

return methodDefBuilder
.setHeaderCommentStatements(
Expand Down Expand Up @@ -1774,6 +1795,7 @@ private static TypeStore createTypes(Service service, Map<String, Message> messa
ApiFutures.class,
BackgroundResource.class,
BetaApi.class,
InternalApi.class,
BidiStreamingCallable.class,
ClientStreamingCallable.class,
Generated.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import com.google.api.core.ApiFunction;
import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.gax.core.GoogleCredentialsProvider;
import com.google.api.gax.core.InstantiatingExecutorProvider;
import com.google.api.gax.rpc.ApiClientHeaderProvider;
Expand Down Expand Up @@ -85,6 +86,8 @@ public abstract class AbstractServiceSettingsClassComposer implements ClassCompo

private static final String OPERATION_SETTINGS_LITERAL = "OperationSettings";
private static final String SETTINGS_LITERAL = "Settings";
private static final String INTERNAL_API_WARNING =
"Internal API. This API is not intended for public consumption.";
protected static final TypeStore FIXED_TYPESTORE = createStaticTypes();

private final TransportContext transportContext;
Expand Down Expand Up @@ -133,16 +136,21 @@ public GapicClass generate(GapicContext context, Service service) {

private static List<CommentStatement> createClassHeaderComments(
Service service, TypeNode classType, List<Sample> samples) {
// Pick the first pure unary rpc method, if no such method exists, then pick the first in the
// Pick the first public pure unary rpc method, if no such method exists, then pick the first
// public in the
// list.
List<Method> publicMethods =
service.methods().stream()
.filter(m -> m.isInternalApi() == false)
.collect(Collectors.toList());
Optional<Method> methodOpt =
service.methods().isEmpty()
publicMethods.isEmpty()
? Optional.empty()
: Optional.of(
service.methods().stream()
publicMethods.stream()
.filter(m -> m.stream() == Stream.NONE && !m.hasLro() && !m.isPaged())
.findFirst()
.orElse(service.methods().get(0)));
.orElse(publicMethods.get(0)));
Optional<String> methodNameOpt =
methodOpt.isPresent() ? Optional.of(methodOpt.get().name()) : Optional.empty();
Optional<Sample> sampleCode =
Expand All @@ -156,9 +164,9 @@ private static List<CommentStatement> createClassHeaderComments(
// Create a sample for a LRO method using LRO-specific RetrySettings, if one exists in the
// service.
Optional<Method> lroMethodOpt =
service.methods().isEmpty()
publicMethods.isEmpty()
? Optional.empty()
: service.methods().stream()
: publicMethods.stream()
.filter(m -> m.stream() == Stream.NONE && m.hasLro())
.findFirst();
Optional<String> lroMethodNameOpt =
Expand Down Expand Up @@ -270,40 +278,44 @@ private static List<MethodDefinition> createSettingsGetterMethods(
List<MethodDefinition> javaMethods = new ArrayList<>();
for (Method protoMethod : service.methods()) {
String javaStyleName = JavaStyle.toLowerCamelCase(protoMethod.name());
String javaMethodName =
String.format("%sSettings", JavaStyle.toLowerCamelCase(protoMethod.name()));
String javaMethodName = String.format("%sSettings", javaStyleName);
MethodDefinition.Builder methodBuilder =
methodMakerFn.apply(getCallSettingsType(protoMethod, typeStore), javaMethodName);
javaMethods.add(
methodBuilder
.setHeaderCommentStatements(
SettingsCommentComposer.createCallSettingsGetterComment(
getMethodNameFromSettingsVarName(javaMethodName), protoMethod.isDeprecated()))
.setAnnotations(
protoMethod.isDeprecated()
? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))
: Collections.emptyList())
.build());
javaMethods.add(methodBuilderHelper(protoMethod, methodBuilder, javaMethodName));
if (protoMethod.hasLro()) {
javaMethodName = String.format("%sOperationSettings", javaStyleName);
methodBuilder =
methodMakerFn.apply(getOperationCallSettingsType(protoMethod), javaMethodName);
javaMethods.add(
methodBuilder
.setHeaderCommentStatements(
SettingsCommentComposer.createCallSettingsGetterComment(
getMethodNameFromSettingsVarName(javaMethodName),
protoMethod.isDeprecated()))
.setAnnotations(
protoMethod.isDeprecated()
? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))
: Collections.emptyList())
.build());
javaMethods.add(methodBuilderHelper(protoMethod, methodBuilder, javaMethodName));
}
}
return javaMethods;
}

// Add method header comment statements and annotations.
private static MethodDefinition methodBuilderHelper(
Method protoMethod, MethodDefinition.Builder methodBuilder, String javaMethodName) {
List<AnnotationNode> annotations = new ArrayList<>();
if (protoMethod.isDeprecated()) {
annotations.add(AnnotationNode.withType(TypeNode.DEPRECATED));
}

if (protoMethod.isInternalApi()) {
annotations.add(
AnnotationNode.withTypeAndDescription(
FIXED_TYPESTORE.get("InternalApi"), INTERNAL_API_WARNING));
}

return methodBuilder
.setHeaderCommentStatements(
SettingsCommentComposer.createCallSettingsGetterComment(
getMethodNameFromSettingsVarName(javaMethodName),
protoMethod.isDeprecated(),
protoMethod.isInternalApi()))
.setAnnotations(annotations)
.build();
}

private static MethodDefinition createCreatorMethod(Service service, TypeStore typeStore) {
TypeNode stubClassType = typeStore.get(ClassNames.getServiceStubSettingsClassName(service));
VariableExpr stubVarExpr =
Expand Down Expand Up @@ -771,7 +783,9 @@ private static List<MethodDefinition> createNestedBuilderSettingsGetterMethods(
methodBuilder
.setHeaderCommentStatements(
SettingsCommentComposer.createCallSettingsBuilderGetterComment(
getMethodNameFromSettingsVarName(javaMethodName), protoMethod.isDeprecated()))
getMethodNameFromSettingsVarName(javaMethodName),
protoMethod.isDeprecated(),
protoMethod.isInternalApi()))
.setAnnotations(
protoMethod.isDeprecated()
? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))
Expand All @@ -787,7 +801,8 @@ private static List<MethodDefinition> createNestedBuilderSettingsGetterMethods(
.setHeaderCommentStatements(
SettingsCommentComposer.createCallSettingsBuilderGetterComment(
getMethodNameFromSettingsVarName(javaMethodName),
protoMethod.isDeprecated()))
protoMethod.isDeprecated(),
protoMethod.isInternalApi()))
.setAnnotations(
protoMethod.isDeprecated()
? Arrays.asList(AnnotationNode.withType(TypeNode.DEPRECATED))
Expand Down Expand Up @@ -822,6 +837,7 @@ private static TypeStore createStaticTypes() {
ApiClientHeaderProvider.class,
ApiFunction.class,
BetaApi.class,
InternalApi.class,
ClientContext.class,
ClientSettings.class,
Generated.class,
Expand Down
Loading
Loading