Skip to content

Commit be0b4e4

Browse files
committed
Merge remote-tracking branch 'origin/main' into observability/tracing-attr/resend_count
# Conflicts: # gax-java/gax/src/main/java/com/google/api/gax/tracing/SpanTracer.java
2 parents 866c45f + e0a33f2 commit be0b4e4

74 files changed

Lines changed: 867 additions & 468 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

GEMINI.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ mvn fmt:format
6565

6666
The repository employs a multi-layered testing strategy to ensure the quality and correctness of the generated code:
6767

68-
* **Unit Tests:** Traditional unit tests for individual classes and methods.
69-
* **Golden Unit Tests:** These tests generate code from test protos and compare the output to "golden" files, which are pre-approved versions of the generated code. These test cases exist inside the `gapic-generator-java` module.
68+
* **Unit Tests:** Traditional unit tests for individual classes and methods. See [unit testing best practices](https://engdoc.corp.google.com/eng/doc/devguide/testing/unit/best-practices.md?cl=head&polyglot=java).
69+
* **Golden Unit Tests:** These tests generate code from test protos and compare the output to "golden" files, which are pre-approved versions of the generated code. These test cases exist inside the `gapic-generator-java` module. See [GrpcServiceStubClassComposerTest](https://github.com/googleapis/sdk-platform-java/blob/main/gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposerTest.java) for an example of golden unit tests. The steps for golden unit tests include creating a test proto, loading the test proto, generating from the test proto, and comparing the result with a golden file.
7070
* **Showcase Integration Tests:** These tests run the generated Showcase client against a local Showcase server to verify end-to-end functionality. This is the preferred way of testing integration tests.
7171
* **Golden Integration Tests:** These tests generate full client libraries for real Google Cloud APIs and compare them to golden versions. This is an older test strategy and showcase testing is preferred.
7272

@@ -144,6 +144,6 @@ Showcase integration tests are run against a local server that implements the Sh
144144
specification. The format is `<type>: <description>`. The type should be one of the following: fix, feat,
145145
build, chore, docs, test, or refactor.
146146
- **Issues:** All significant changes should start with a GitHub issue.
147-
- **Pull Requests:** All code changes must be submitted via a pull request and require review.
147+
- **Pull Requests:** All code changes must be submitted via a pull request and require review. Before creating a PR, always pull latest from main, merge main to local branch and resolve any conflicts.
148148
- **Testing:** All new logic should be accompanied by tests.
149149
- For more details, see `CONTRIBUTING.md`.

gapic-generator-java/src/main/java/com/google/api/generator/engine/ast/ClassDefinition.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,6 @@ public ClassDefinition build() {
203203
expr instanceof AssignmentExpr,
204204
"Class expression statement must be assignment or variable declaration");
205205
VariableExpr variableExpr = ((AssignmentExpr) expr).variableExpr();
206-
Preconditions.checkState(
207-
!variableExpr.scope().equals(ScopeNode.LOCAL),
208-
"Class variable in assignment statement cannot have a local scope");
209206
}
210207
}
211208
}

gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/Composer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public static List<GapicClass> generateServiceClasses(GapicContext context) {
6969
clazzes.addAll(generateClientSettingsClasses(context));
7070
clazzes.addAll(generateMockClasses(context, context.services()));
7171
clazzes.addAll(generateTestClasses(context));
72+
clazzes.addAll(generateVersionClasses(context));
7273
return clazzes;
7374
}
7475

@@ -197,6 +198,15 @@ public static List<GapicClass> generateTestClasses(GapicContext context) {
197198
return clazzes;
198199
}
199200

201+
public static List<GapicClass> generateVersionClasses(GapicContext context) {
202+
return context.services().stream()
203+
.collect(Collectors.toMap(Service::pakkage, s -> s, (s1, s2) -> s1))
204+
.values()
205+
.stream()
206+
.map(service -> LibraryVersionClassComposer.instance().generate(context, service))
207+
.collect(Collectors.toList());
208+
}
209+
200210
@VisibleForTesting
201211
static List<GapicClass> prepareExecutableSamples(List<GapicClass> clazzes) {
202212
// Include license header, apiShortName, and apiVersion
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.api.generator.gapic.composer;
16+
17+
import com.google.api.generator.engine.ast.AnnotationNode;
18+
import com.google.api.generator.engine.ast.AssignmentExpr;
19+
import com.google.api.generator.engine.ast.ClassDefinition;
20+
import com.google.api.generator.engine.ast.CommentStatement;
21+
import com.google.api.generator.engine.ast.ConcreteReference;
22+
import com.google.api.generator.engine.ast.ExprStatement;
23+
import com.google.api.generator.engine.ast.LineComment;
24+
import com.google.api.generator.engine.ast.ScopeNode;
25+
import com.google.api.generator.engine.ast.StringObjectValue;
26+
import com.google.api.generator.engine.ast.TypeNode;
27+
import com.google.api.generator.engine.ast.ValueExpr;
28+
import com.google.api.generator.engine.ast.Variable;
29+
import com.google.api.generator.engine.ast.VariableExpr;
30+
import com.google.api.generator.gapic.model.GapicClass;
31+
import com.google.api.generator.gapic.model.GapicContext;
32+
import com.google.api.generator.gapic.model.Service;
33+
import java.util.Arrays;
34+
35+
public class LibraryVersionClassComposer {
36+
private static final LibraryVersionClassComposer INSTANCE = new LibraryVersionClassComposer();
37+
38+
private LibraryVersionClassComposer() {}
39+
40+
public static LibraryVersionClassComposer instance() {
41+
return INSTANCE;
42+
}
43+
44+
public GapicClass generate(GapicContext context, Service service) {
45+
String packageName = service.pakkage() + ".stub";
46+
String className = "Version";
47+
48+
String artifact = context.artifact();
49+
String artifactId = artifact;
50+
if (artifact != null && artifact.contains(":")) {
51+
artifactId = artifact.split(":")[1];
52+
}
53+
54+
VariableExpr versionVarExpr =
55+
VariableExpr.withVariable(
56+
Variable.builder().setType(TypeNode.STRING).setName("VERSION").build());
57+
AssignmentExpr versionAssignmentExpr =
58+
AssignmentExpr.builder()
59+
.setVariableExpr(
60+
versionVarExpr.toBuilder()
61+
.setIsDecl(true)
62+
.setScope(ScopeNode.LOCAL)
63+
.setIsStatic(true)
64+
.setIsFinal(true)
65+
.build())
66+
.setValueExpr(ValueExpr.withValue(StringObjectValue.withValue("0.0.0-SNAPSHOT")))
67+
.build();
68+
69+
ClassDefinition classDef =
70+
ClassDefinition.builder()
71+
.setPackageString(packageName)
72+
.setAnnotations(
73+
Arrays.asList(
74+
AnnotationNode.builder()
75+
.setType(
76+
TypeNode.withReference(
77+
ConcreteReference.withClazz(com.google.api.core.InternalApi.class)))
78+
.setDescription("For internal use only")
79+
.build()))
80+
.setScope(ScopeNode.LOCAL)
81+
.setIsFinal(true)
82+
.setName(className)
83+
.setStatements(
84+
Arrays.asList(
85+
CommentStatement.withComment(
86+
LineComment.withComment(
87+
String.format("{x-version-update-start:%s:current}", artifactId))),
88+
ExprStatement.withExpr(versionAssignmentExpr),
89+
CommentStatement.withComment(
90+
LineComment.withComment("{x-version-update-end}"))))
91+
.build();
92+
93+
return GapicClass.create(GapicClass.Kind.MAIN, classDef);
94+
}
95+
}

gapic-generator-java/src/main/java/com/google/api/generator/gapic/composer/common/AbstractServiceStubSettingsClassComposer.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ private List<MethodDefinition> createClassMethods(
10631063
SettingsCommentComposer.NEW_BUILDER_METHOD_COMMENT));
10641064
javaMethods.addAll(createBuilderHelperMethods(service, typeStore));
10651065
javaMethods.add(createClassConstructor(service, methodSettingsMemberVarExprs, typeStore));
1066-
javaMethods.add(createGetLibraryMetadataMethod(context));
1066+
javaMethods.add(createGetLibraryMetadataMethod(context, service));
10671067
return javaMethods;
10681068
}
10691069

@@ -2107,7 +2107,7 @@ private static MethodDefinition createNestedClassBuildMethod(
21072107
.build();
21082108
}
21092109

2110-
private MethodDefinition createGetLibraryMetadataMethod(GapicContext context) {
2110+
private MethodDefinition createGetLibraryMetadataMethod(GapicContext context, Service service) {
21112111
TypeNode returnType = FIXED_TYPESTORE.get("LibraryMetadata");
21122112
MethodInvocationExpr libraryMetadataBuilderExpr =
21132113
MethodInvocationExpr.builder()
@@ -2133,6 +2133,23 @@ private MethodDefinition createGetLibraryMetadataMethod(GapicContext context) {
21332133
.build();
21342134
}
21352135

2136+
libraryMetadataBuilderExpr =
2137+
MethodInvocationExpr.builder()
2138+
.setExprReferenceExpr(libraryMetadataBuilderExpr)
2139+
.setMethodName("setVersion")
2140+
.setArguments(
2141+
VariableExpr.builder()
2142+
.setStaticReferenceType(
2143+
TypeNode.withReference(
2144+
VaporReference.builder()
2145+
.setName("Version")
2146+
.setPakkage(String.format("%s.stub", service.pakkage()))
2147+
.build()))
2148+
.setVariable(
2149+
Variable.builder().setName("VERSION").setType(TypeNode.STRING).build())
2150+
.build())
2151+
.build();
2152+
21362153
Expr returnExpr =
21372154
MethodInvocationExpr.builder()
21382155
.setExprReferenceExpr(libraryMetadataBuilderExpr)

gapic-generator-java/src/test/java/com/google/api/generator/engine/ast/ClassDefinitionTest.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -293,31 +293,6 @@ void invalidClassDefinition_extendsImplementsSameType() {
293293
});
294294
}
295295

296-
@Test
297-
void invalidClassDefinition_assignmentWithUnscopedVariableExprStatement() {
298-
Variable variable = createVariable("x", TypeNode.INT);
299-
VariableExpr variableExpr =
300-
VariableExpr.builder().setVariable(variable).setIsDecl(true).build();
301-
302-
Variable anotherVariable = createVariable("y", TypeNode.INT);
303-
Expr valueExpr = VariableExpr.builder().setVariable(anotherVariable).build();
304-
305-
AssignmentExpr assignmentExpr =
306-
AssignmentExpr.builder().setVariableExpr(variableExpr).setValueExpr(valueExpr).build();
307-
308-
List<Statement> statements = Arrays.asList(ExprStatement.withExpr(assignmentExpr));
309-
assertThrows(
310-
IllegalStateException.class,
311-
() -> {
312-
ClassDefinition.builder()
313-
.setPackageString("com.google.example.library.v1.stub")
314-
.setName("LibraryServiceStub")
315-
.setScope(ScopeNode.PUBLIC)
316-
.setStatements(statements)
317-
.build();
318-
});
319-
}
320-
321296
@Test
322297
void invalidClassDefinition_unscopedVariableExprStatement() {
323298
List<Statement> statements =
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.api.generator.gapic.composer;
16+
17+
import com.google.api.generator.gapic.model.GapicClass;
18+
import com.google.api.generator.gapic.model.GapicContext;
19+
import com.google.api.generator.gapic.model.Service;
20+
import com.google.api.generator.test.framework.Assert;
21+
import com.google.api.generator.test.protoloader.GrpcTestProtoLoader;
22+
import org.junit.Test;
23+
24+
public class LibraryVersionClassComposerTest {
25+
26+
@Test
27+
public void generateVersionClasses() {
28+
GapicContext context = GrpcTestProtoLoader.instance().parseShowcaseEcho();
29+
Service service = context.services().get(0);
30+
GapicClass clazz = LibraryVersionClassComposer.instance().generate(context, service);
31+
32+
Assert.assertGoldenClass(this.getClass(), clazz, "EchoVersion.golden");
33+
}
34+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.google.showcase.v1beta1.stub;
2+
3+
import com.google.api.core.InternalApi;
4+
5+
@InternalApi("For internal use only")
6+
final class Version {
7+
// {x-version-update-start:gapic-showcase:current}
8+
static final String VERSION = "0.0.0-SNAPSHOT";
9+
// {x-version-update-end}
10+
11+
}

gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/ApiVersionTestingStubSettings.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public class EchoWithVersionStubSettings extends StubSettings<EchoWithVersionStu
170170

171171
@Override
172172
protected LibraryMetadata getLibraryMetadata() {
173-
return LibraryMetadata.newBuilder().build();
173+
return LibraryMetadata.newBuilder().setVersion(Version.VERSION).build();
174174
}
175175

176176
/** Builder for EchoWithVersionStubSettings. */

gapic-generator-java/src/test/java/com/google/api/generator/gapic/composer/grpc/goldens/DeprecatedServiceStubSettings.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public class DeprecatedServiceStubSettings extends StubSettings<DeprecatedServic
187187

188188
@Override
189189
protected LibraryMetadata getLibraryMetadata() {
190-
return LibraryMetadata.newBuilder().build();
190+
return LibraryMetadata.newBuilder().setVersion(Version.VERSION).build();
191191
}
192192

193193
/** Builder for DeprecatedServiceStubSettings. */

0 commit comments

Comments
 (0)