-
Notifications
You must be signed in to change notification settings - Fork 54
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
feat: DIREGAPIC initial implementation #746
Conversation
Codecov Report
@@ Coverage Diff @@
## master #746 +/- ##
==========================================
+ Coverage 91.30% 91.66% +0.35%
==========================================
Files 133 140 +7
Lines 13900 14697 +797
Branches 1032 1051 +19
==========================================
+ Hits 12692 13472 +780
- Misses 927 941 +14
- Partials 281 284 +3
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a first pass, will do a finer-grained review on the next one.
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse; | ||
import java.io.IOException; | ||
|
||
public class MainDumper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be really useful. Could we move this into a debug-only subpackage (to separate this from the main generator logic) and rename this class to something like GeneratorRequestDumper
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this PR, will add in a separate one, incorporating the PR feedback.
} | ||
|
||
/** Register all extensions needed to process API protofiles. */ | ||
private static void registerAllExtensions(ExtensionRegistry extensionRegistry) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're doing this in three places now, can we centralize this? We can have a minimal standalone class (e.g. in a generator.registry
package) that has just this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this PR, will add in a separate one, incorporating the PR feedback.
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
|
||
public class MainFromFile { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as the above comment, could we please move this into a debug-specific package and use a more descriptive name (e.g. GapicLibraryDumper
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this PR, will add in a separate one, incorporating the PR feedback.
import java.io.OutputStream; | ||
|
||
public class MainFromFile { | ||
public static void main(String[] args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a usage example, same for the other debug class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this PR, will add in a separate one, incorporating the PR feedback.
BUILD.bazel
Outdated
@@ -45,6 +45,32 @@ java_binary( | |||
], | |||
) | |||
|
|||
java_binary( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is independent of DIREGAPIC, could we please split this out into a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from this PR, will add in a separate one, incorporating the PR feedback.
src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java
Show resolved
Hide resolved
private static Set<String> getHttpVerbPattern(HttpRule httpRule) { | ||
String pattern = null; | ||
// Assign a temp variable to prevent the formatter from removing the import. | ||
private static String getPattern(HttpRule httpRule) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getHttpRulePattern
or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess, originally it was called as getPattern
, then in one of the recent PRs you renamed it to getHttpVerbPattern
and on merge I overrode it back to getPattern
. Renamed it to its recent updated name getHttpVerbPattern
.
Sets.difference(inputMessageOpt.get().fieldMap().keySet(), bodyBinidngsUnion); | ||
} | ||
|
||
HttpRuleBindings.Builder httpBindings = HttpRuleBindings.builder(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Can we use the chained builder pattern for consistency? e.g. builder().setFoo().set... .build()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sure. No idea why I used this style here. Refactored to inline return statement with chained builder.
|
||
HttpRuleBindings.Builder httpBindings = HttpRuleBindings.builder(); | ||
httpBindings.setHttpVerb(httpRule.getPatternCase().toString()); | ||
httpBindings.setPattern(pattern); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about a version of setPattern
that takes a PatternCase
? Then we can move getPattern
into HttpRuleBindings
, where it fits better anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, I think the whole parsing logic must be moved to HttpRuleBindings
. I.e. the current architecture has a split between the class which simply contains the values (HttpRuleBindings
, a simple POJO, javabean, whatever), and HttpRuleParser
- one of potential classes, which knows how to populate HttpRuleBinding
class from a HttpRule. So basically HttpRuleBindings
class is detached from HttpRule per se, and may be populated from another source by some other sort of parser or manually. From my experience splitting this stuff into two classes (one contains values, the other one (or a set of, one for each source) knows how to populate those values from a source) usually works better in a long run (especially if a persistence layer is used, like a database, though this is irrelevant here). I can merge them, if you wish, though, I don't have a strong preference here.
src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java
Show resolved
Hide resolved
…tes for existing integration tests. Will do that in next PR (the update of googleapis is needed for integration test for compute)
rules_java_gapic/java_gapic.bzl
Outdated
@@ -127,12 +127,14 @@ def java_gapic_library( | |||
service_yaml = None, | |||
deps = [], | |||
test_deps = [], | |||
transport = None, | |||
java_generator_name = "java_gapic", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SG, could we please add some documentation here? And since this is intended only for our use, could we please make this fail if the string does not match the generator or the dumpers' values?
private static final HttpJsonServiceStubClassComposer INSTANCE = | ||
new HttpJsonServiceStubClassComposer(); | ||
|
||
protected static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant FIXED_REST_TYPESTORE
, but I see now they're actually different. In that case, could we make this one private?
Expr returnExpr = null; | ||
VariableExpr fieldsVarExpr = null; | ||
Expr serializerExpr = null; | ||
if (!extractorReturnType.isProtoPrimitiveType()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we please flip the if-blocks so the shorter one comes first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, is there a best practice about this? conditional return/continue
is preferred to go first but it is not quite the same as if-else block, after which method continues. Or is it about using not in if-else (as if else always covers both true and !true cases in any case) Well, anyways, flipped.
paramsPutArgs.add(requestBuilderExpr); | ||
|
||
if (fieldsVarExpr == null) { | ||
Expr paramsPutExpr = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps I'm missing something, but this looks the same as the if-block. Can we move this assignment out, and leave just the returnExpr
/ bodyExprs.add()
logic inside?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess centennially they were different, as since one of them was missing setReturnType(), but the one with setReturnType matches both cases, so moved it out.
.setPattern("") | ||
.setPathParameters(ImmutableSet.of()) | ||
.setQueryParameters(ImmutableSet.of()) | ||
.setBodyParameters(ImmutableSet.of()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, we probably shouldn't be able to instantiate an HttpRuleBindings at all (or we'd be able to set an empty pattern and verb with non-empty parameter lists). Could we do the following instead?
- Make
HttpRuleBindings
Nullable
onMethod
- Remove the empty string setters here, and add checks in
build()
to fail on invalid cases (i.e. empty string, pattern has no slashes and is not PubSub's_deleted-topic_
, etc). - Consider making the verb an enum, or check that the string is one of the accepted five values in
build()
. (Would prefer the enum, since the latter is more error-prone.)
Context: Using rigorous validity checks has really helped me with development in this codebase. For instance, adding type-checking on assignment expressions or requiring set types on methods has helped me catch those errors at compile-time, so I think more rigid checks would help us here as well.
src/main/java/com/google/api/generator/gapic/model/HttpRuleBindings.java
Outdated
Show resolved
Hide resolved
// HttpBinding pending dotted reference support. | ||
public abstract List<String> httpBindings(); | ||
public abstract HttpRuleBindings httpBindings(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continuing the comment above; Can we put a @Nullable
on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really would rather not have null
s for things like this. Please check the other comments about HttpBindings. WDYT about renaming the HttpRuleBindings
to just HttpBindings
to make things clearer that this class is not strictly about the google.api.http
option in proto files.
src/main/java/com/google/api/generator/gapic/protoparser/HttpRuleParser.java
Show resolved
Hide resolved
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
public class RestTestProtoLoader extends TestProtoLoader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Since all the classes are prefixed with HttpJson, should we do that here too for consistency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was intentional, and as consistent as i could make it. The generated files are named HttpJson<Smth>
because they generate HttpJson<Smth>
so it would comply with naming pattern of composer-generated_class. For everything else, the "rest" is used for naming.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving the HttpRuleBindings discussion as-is so we can discuss more next week.
rules_java_gapic/java_gapic.bzl
Outdated
@@ -127,12 +127,14 @@ def java_gapic_library( | |||
service_yaml = None, | |||
deps = [], | |||
test_deps = [], | |||
transport = None, | |||
java_generator_name = "java_gapic", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, although some documentation would still be ideal.
Could you please check if the commits have been pushed? I'm still seeing the param without the leading underscore.
private static final ServiceStubSettingsClassComposer INSTANCE = | ||
new ServiceStubSettingsClassComposer(); | ||
|
||
protected static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I would prefer this to be privately-scoped, since it's meant to be used just in this class (so it is not consistent with FIXED_TYPESTORE
by nature).
src/main/java/com/google/api/generator/gapic/composer/rest/ServiceClientTestClassComposer.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with the following addressed:
- Can we flip these blocks (from the last round)?
- PTAL at this comment from the last round
- Can we make this
FIXED_REST_TYPESTORE
privately scoped as well? - Nit on L81 of HttpBindings - could we please use
!pattern.isEmpty()
instead of"".equals(pattern)
? - PTAL at this comment on L290 of GrpcServiceStubComposer.java?
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
public class RestTestProtoLoader extends TestProtoLoader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM.
src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java
Show resolved
Hide resolved
@miraleung Thanks for the reveiw! More detailed responses are at each specific comment, but briefly:
|
@miraleung PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with commented-out code removed.
src/main/java/com/google/api/generator/gapic/composer/grpc/GrpcServiceStubClassComposer.java
Show resolved
Hide resolved
FIXED_REST_TYPESTORE.get(ProtoMessageRequestFormatter.class.getSimpleName())) | ||
.setMethodName("newBuilder") | ||
.setGenerics(Collections.singletonList(protoMethod.inputType().reference())) | ||
// .setArguments(Arrays.asList(m)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Remove?
🤖 I have created a release *beep* *boop* --- ## [3.0.0](googleapis/java-shared-dependencies@v2.13.0...v3.0.0) (2022-07-29) ### Bug Fixes * enable longpaths support for windows test ([#1485](https://github.com/googleapis/java-shared-dependencies/issues/1485)) ([#738](googleapis/java-shared-dependencies#738)) ([48b157d](googleapis/java-shared-dependencies@48b157d)) ### Dependencies * update dependency com.google.api-client:google-api-client-bom to v1.35.2 ([#729](googleapis/java-shared-dependencies#729)) ([d518319](googleapis/java-shared-dependencies@d518319)) * update dependency com.google.api-client:google-api-client-bom to v2 ([#746](googleapis/java-shared-dependencies#746)) ([ef2b57a](googleapis/java-shared-dependencies@ef2b57a)) * update dependency com.google.api.grpc:grpc-google-common-protos to v2.9.2 ([#741](googleapis/java-shared-dependencies#741)) ([347269f](googleapis/java-shared-dependencies@347269f)) * update dependency com.google.auth:google-auth-library-bom to v1.8.0 ([#726](googleapis/java-shared-dependencies#726)) ([236bbb3](googleapis/java-shared-dependencies@236bbb3)) * update dependency com.google.auth:google-auth-library-bom to v1.8.1 ([#742](googleapis/java-shared-dependencies#742)) ([dabdbdf](googleapis/java-shared-dependencies@dabdbdf)) * update dependency com.google.cloud:first-party-dependencies to v2 ([#747](googleapis/java-shared-dependencies#747)) ([93b1ed8](googleapis/java-shared-dependencies@93b1ed8)) * update dependency com.google.cloud:grpc-gcp to v1.2.1 ([#751](googleapis/java-shared-dependencies#751)) ([618b00c](googleapis/java-shared-dependencies@618b00c)) * update dependency com.google.cloud:third-party-dependencies to v2 ([#748](googleapis/java-shared-dependencies#748)) ([afca3fd](googleapis/java-shared-dependencies@afca3fd)) * update dependency com.google.http-client:google-http-client-bom to v1.42.1 ([#730](googleapis/java-shared-dependencies#730)) ([4fdaad8](googleapis/java-shared-dependencies@4fdaad8)) * update dependency com.google.http-client:google-http-client-bom to v1.42.2 ([#749](googleapis/java-shared-dependencies#749)) ([68a82f4](googleapis/java-shared-dependencies@68a82f4)) * update dependency com.google.protobuf:protobuf-bom to v3.21.2 ([#722](googleapis/java-shared-dependencies#722)) ([68f570e](googleapis/java-shared-dependencies@68f570e)) * update dependency com.google.protobuf:protobuf-bom to v3.21.3 ([#756](googleapis/java-shared-dependencies#756)) ([7429507](googleapis/java-shared-dependencies@7429507)) * update dependency com.google.protobuf:protobuf-bom to v3.21.4 ([#759](googleapis/java-shared-dependencies#759)) ([f033db0](googleapis/java-shared-dependencies@f033db0)) * update dependency io.grpc:grpc-bom to v1.48.0 ([#752](googleapis/java-shared-dependencies#752)) ([9678d52](googleapis/java-shared-dependencies@9678d52)) * update dependency org.checkerframework:checker-qual to v3.23.0 ([#736](googleapis/java-shared-dependencies#736)) ([816d380](googleapis/java-shared-dependencies@816d380)) * update gax.version to v2.18.3 ([#731](googleapis/java-shared-dependencies#731)) ([5bbf1e1](googleapis/java-shared-dependencies@5bbf1e1)) * update gax.version to v2.18.4 ([#735](googleapis/java-shared-dependencies#735)) ([5161c6e](googleapis/java-shared-dependencies@5161c6e)) * update gax.version to v2.18.5 ([#758](googleapis/java-shared-dependencies#758)) ([608e040](googleapis/java-shared-dependencies@608e040)) * update gax.version to v2.18.6 ([#763](googleapis/java-shared-dependencies#763)) ([84b81e9](googleapis/java-shared-dependencies@84b81e9)) * update google.common-protos.version to v2.9.1 ([#724](googleapis/java-shared-dependencies#724)) ([62cd59a](googleapis/java-shared-dependencies@62cd59a)) * update google.core.version to v2.8.1 ([#725](googleapis/java-shared-dependencies#725)) ([d47af56](googleapis/java-shared-dependencies@d47af56)) * update google.core.version to v2.8.3 ([#760](googleapis/java-shared-dependencies#760)) ([33e38dc](googleapis/java-shared-dependencies@33e38dc)) * update google.core.version to v2.8.4 ([#762](googleapis/java-shared-dependencies#762)) ([5410450](googleapis/java-shared-dependencies@5410450)) * update google.core.version to v2.8.5 ([#764](googleapis/java-shared-dependencies#764)) ([4bc8c75](googleapis/java-shared-dependencies@4bc8c75)) * update iam.version to v1.5.0 ([#732](googleapis/java-shared-dependencies#732)) ([3e64541](googleapis/java-shared-dependencies@3e64541)) * update iam.version to v1.5.1 ([#737](googleapis/java-shared-dependencies#737)) ([5a85115](googleapis/java-shared-dependencies@5a85115)) * update iam.version to v1.5.2 ([#743](googleapis/java-shared-dependencies#743)) ([294ea85](googleapis/java-shared-dependencies@294ea85)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Integration tests (compute_small) are not present in this commit, as they depend on #743 and #744. Also, as a prerequisite, at least a basic implementation of DIREGAPIC must be merged in gapic-generator-java, to integrate it with googleapis-discovery first (since integration test infra depends on the actual googleapis/googleapis-discovery targets). Please check vam-google@8983e23 to see how it would look like with compute integration tests not excluded.
compliance.proto
is used as a basis for the REST composer tests. It was copied as is from showcase/compliance.proto.Changes in
WORKSPACE
andrepositories.bzl
are necessary to make this repo work with gax-java1.63.0
and above (gax-java
vsgapic-generator-java
java dependencies imports precedence). The other dependencies changes are either to bring deps in sync with the actual ones in googleapis, or to fix a specific import precedence issue.I also added (in a form of bazel rules) a proto descriptor dumper and a runner from the dumped file (for debugging purposes). Not technically required here (but was very helpful for debugging purposes, so hopefully we can preserve it).