Skip to content
This repository has been archived by the owner on Jun 28, 2022. It is now read-only.

Commit

Permalink
feat: Add support for optional field in HttpJson stubs for Java (#3356
Browse files Browse the repository at this point in the history
)

This PR also updates the dependency to protobuf `3.15.8`, and the chagnes ini baseline files for the othe langauges but Java are caused by the update to the protobuf dependency and are not caused by the chagnes in the generator.
  • Loading branch information
vam-google authored Apr 30, 2021
1 parent 86f2cb6 commit 893447f
Show file tree
Hide file tree
Showing 16 changed files with 239 additions and 120 deletions.
2 changes: 1 addition & 1 deletion dependencies.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Target workspace name: com_google_api_codegen

# Versions only, for dependencies which actual artifacts differ between Bazel and Gradle
version.com_google_protobuf=3.13.0
version.com_google_protobuf=3.15.8
version.google_java_format=1.6

# Maven artifacts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,23 @@ private List<HttpMethodSelectorView> populateMethodSelectors(
HttpMethodSelectorView.Builder methodSelectorView = HttpMethodSelectorView.newBuilder();
methodSelectorView.fullyQualifiedName(Name.anyLower(fs.toString()).toLowerCamel());
ImmutableList.Builder<String> gettersChain = ImmutableList.builder();
ImmutableList.Builder<String> gettersHasChain = ImmutableList.builder();
ProtoField pf = null;
for (Field f : fs.getFields()) {
gettersChain.add(namer.getFieldGetFunctionName(new ProtoField(f)));
if (pf != null) {
gettersHasChain.add(namer.getFieldGetFunctionName(pf));
}
pf = new ProtoField(f);
gettersChain.add(namer.getFieldGetFunctionName(pf));
}
methodSelectorView.gettersChain(gettersChain.build());
if (pf != null && pf.getProtoField().getProto().getProto3Optional()) {
gettersHasChain.add(namer.getFieldHasFunctionName(pf));
methodSelectorView.gettersHasChain(gettersHasChain.build());
} else {
methodSelectorView.gettersHasChain(ImmutableList.of());
}

paramSelectors.add(methodSelectorView.build());
}

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/google/api/codegen/transformer/SurfaceNamer.java
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,21 @@ public String getFieldGetFunctionName(Name identifier, MapType mapType, Cardinal
}
}

public String getFieldHasFunctionName(FieldModel field) {
return getFieldHasFunctionName(
field.getNameAsParameterName(),
MapType.ofMap(field.isMap()),
Cardinality.ofRepeated(field.isRepeated()));
}

public String getFieldHasFunctionName(Name identifier, MapType mapType, Cardinality cardinality) {
if (mapType == MapType.IS_MAP && cardinality == Cardinality.IS_REPEATED) {
throw new IllegalArgumentException("Maps and repeated fields don't have has*() methods");
} else {
return publicMethodName(Name.from("has").join(identifier));
}
}

/** The function name to get a field having the given type and name. */
public String getFieldGetFunctionName(TypeModel type, Name identifier) {
return getFieldGetFunctionName(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ public abstract class HttpMethodSelectorView {

public abstract List<String> gettersChain();

public abstract List<String> gettersHasChain();

public boolean isProto3Optional() {
return !gettersHasChain().isEmpty();
}

public static HttpMethodSelectorView.Builder newBuilder() {
return new AutoValue_HttpMethodSelectorView.Builder();
}
Expand All @@ -19,6 +25,8 @@ public abstract static class Builder {

public abstract Builder gettersChain(List<String> val);

public abstract Builder gettersHasChain(List<String> val);

public abstract HttpMethodSelectorView build();
}
}
8 changes: 7 additions & 1 deletion src/main/resources/com/google/api/codegen/java/stub.snip
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@

@private queryMethodSelectors(methodSelectors)
@join methodSelector : @methodSelectors
serializer.putQueryParam(fields, "{@methodSelector.fullyQualifiedName}", request.{@methodSelectorGetter(methodSelector.gettersChain)});
@if methodSelector.isProto3Optional
if (request.{@methodSelectorGetter(methodSelector.gettersHasChain)}) {
serializer.putQueryParam(fields, "{@methodSelector.fullyQualifiedName}", request.{@methodSelectorGetter(methodSelector.gettersChain)});
}
@else
serializer.putQueryParam(fields, "{@methodSelector.fullyQualifiedName}", request.{@methodSelectorGetter(methodSelector.gettersChain)});
@end
@end
@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
emptypbpb "google.golang.org/protobuf/types/known/emptypb"
)

// CallOptions contains the retry settings for each method of LibClient.
Expand Down Expand Up @@ -2004,10 +2005,10 @@ package library
import (
pb ""

emptypb "github.com/golang/protobuf/ptypes/empty"
librarypb "google.golang.org/genproto/googleapis/example/library/v1"
longrunningpb "google.golang.org/genproto/googleapis/longrunning"
taggerpb "google.golang.org/genproto/googleapis/tagger/v1"
emptypbpb "google.golang.org/protobuf/types/known/emptypb"
)

import (
Expand Down Expand Up @@ -2086,7 +2087,7 @@ func (s *mockLibraryServer) ListShelves(ctx context.Context, req *librarypb.List
return s.resps[0].(*librarypb.ListShelvesResponse), nil
}

func (s *mockLibraryServer) DeleteShelf(ctx context.Context, req *librarypb.DeleteShelfRequest) (*emptypb.Empty, error) {
func (s *mockLibraryServer) DeleteShelf(ctx context.Context, req *librarypb.DeleteShelfRequest) (*emptypbpb.Empty, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
Expand All @@ -2095,7 +2096,7 @@ func (s *mockLibraryServer) DeleteShelf(ctx context.Context, req *librarypb.Dele
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*emptypb.Empty), nil
return s.resps[0].(*emptypbpb.Empty), nil
}

func (s *mockLibraryServer) MergeShelves(ctx context.Context, req *librarypb.MergeShelvesRequest) (*librarypb.Shelf, error) {
Expand Down Expand Up @@ -2158,7 +2159,7 @@ func (s *mockLibraryServer) ListBooks(ctx context.Context, req *librarypb.ListBo
return s.resps[0].(*librarypb.ListBooksResponse), nil
}

func (s *mockLibraryServer) DeleteBook(ctx context.Context, req *librarypb.DeleteBookRequest) (*emptypb.Empty, error) {
func (s *mockLibraryServer) DeleteBook(ctx context.Context, req *librarypb.DeleteBookRequest) (*emptypbpb.Empty, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
Expand All @@ -2167,7 +2168,7 @@ func (s *mockLibraryServer) DeleteBook(ctx context.Context, req *librarypb.Delet
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*emptypb.Empty), nil
return s.resps[0].(*emptypbpb.Empty), nil
}

func (s *mockLibraryServer) UpdateBook(ctx context.Context, req *librarypb.UpdateBookRequest) (*librarypb.Book, error) {
Expand Down Expand Up @@ -2206,7 +2207,7 @@ func (s *mockLibraryServer) ListStrings(ctx context.Context, req *librarypb.List
return s.resps[0].(*librarypb.ListStringsResponse), nil
}

func (s *mockLibraryServer) AddComments(ctx context.Context, req *librarypb.AddCommentsRequest) (*emptypb.Empty, error) {
func (s *mockLibraryServer) AddComments(ctx context.Context, req *librarypb.AddCommentsRequest) (*emptypbpb.Empty, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
Expand All @@ -2215,7 +2216,7 @@ func (s *mockLibraryServer) AddComments(ctx context.Context, req *librarypb.AddC
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*emptypb.Empty), nil
return s.resps[0].(*emptypbpb.Empty), nil
}

func (s *mockLibraryServer) GetBookFromAnywhere(ctx context.Context, req *librarypb.GetBookFromAnywhereRequest) (*librarypb.BookFromAnywhere, error) {
Expand All @@ -2242,7 +2243,7 @@ func (s *mockLibraryServer) GetBookFromAbsolutelyAnywhere(ctx context.Context, r
return s.resps[0].(*librarypb.BookFromAnywhere), nil
}

func (s *mockLibraryServer) UpdateBookIndex(ctx context.Context, req *librarypb.UpdateBookIndexRequest) (*emptypb.Empty, error) {
func (s *mockLibraryServer) UpdateBookIndex(ctx context.Context, req *librarypb.UpdateBookIndexRequest) (*emptypbpb.Empty, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
Expand All @@ -2251,7 +2252,7 @@ func (s *mockLibraryServer) UpdateBookIndex(ctx context.Context, req *librarypb.
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*emptypb.Empty), nil
return s.resps[0].(*emptypbpb.Empty), nil
}

func (s *mockLibraryServer) StreamShelves(req *librarypb.StreamShelvesRequest, stream librarypb.LibraryService_StreamShelvesServer) error {
Expand Down Expand Up @@ -2350,7 +2351,7 @@ func (s *mockLibraryServer) BabbleAboutBook(stream librarypb.LibraryService_Babb
if s.err != nil {
return s.err
}
return stream.SendAndClose(s.resps[0].(*emptypb.Empty))
return stream.SendAndClose(s.resps[0].(*emptypbpb.Empty))
}

func (s *mockLibraryServer) FindRelatedBooks(ctx context.Context, req *librarypb.FindRelatedBooksRequest) (*librarypb.FindRelatedBooksResponse, error) {
Expand Down Expand Up @@ -2450,7 +2451,7 @@ func (s *mockLibraryServer) StreamingArchiveBooks(stream librarypb.LibraryServic
return nil
}

func (s *mockLibraryServer) SaveBook(ctx context.Context, req *librarypb.Book) (*emptypb.Empty, error) {
func (s *mockLibraryServer) SaveBook(ctx context.Context, req *librarypb.Book) (*emptypbpb.Empty, error) {
md, _ := metadata.FromIncomingContext(ctx)
if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
Expand All @@ -2459,7 +2460,7 @@ func (s *mockLibraryServer) SaveBook(ctx context.Context, req *librarypb.Book) (
if s.err != nil {
return nil, s.err
}
return s.resps[0].(*emptypb.Empty), nil
return s.resps[0].(*emptypbpb.Empty), nil
}

func (s *mockLibraryServer) TestOptionalRequiredFlatteningParams(ctx context.Context, req *librarypb.TestOptionalRequiredFlatteningParamsRequest) (*librarypb.TestOptionalRequiredFlatteningParamsResponse, error) {
Expand Down Expand Up @@ -2783,7 +2784,7 @@ func TestLibraryServiceListShelvesError(t *testing.T) {
_ = resp
}
func TestLibraryServiceDeleteShelf(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down Expand Up @@ -3190,7 +3191,7 @@ func TestLibraryServiceListBooksError(t *testing.T) {
_ = resp
}
func TestLibraryServiceDeleteBook(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down Expand Up @@ -3446,7 +3447,7 @@ func TestLibraryServiceListStringsError(t *testing.T) {
_ = resp
}
func TestLibraryServiceAddComments(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down Expand Up @@ -3652,7 +3653,7 @@ func TestLibraryServiceGetBookFromAbsolutelyAnywhereError(t *testing.T) {
_ = resp
}
func TestLibraryServiceUpdateBookIndex(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down Expand Up @@ -4015,7 +4016,7 @@ func TestLibraryServiceMonologAboutBookError(t *testing.T) {
_ = resp
}
func TestLibraryServiceBabbleAboutBook(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down Expand Up @@ -4304,7 +4305,7 @@ func TestLibraryServiceGetBigBookError(t *testing.T) {
_ = resp
}
func TestLibraryServiceGetBigNothing(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down Expand Up @@ -4784,7 +4785,7 @@ func TestLibraryServiceStreamingArchiveBooksError(t *testing.T) {
_ = resp
}
func TestLibraryServiceSaveBook(t *testing.T) {
var expectedResponse *emptypb.Empty = &emptypb.Empty{}
var expectedResponse *emptypbpb.Empty = &emptypbpb.Empty{}

mockLibrary.err = nil
mockLibrary.reqs = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3177,10 +3177,13 @@ const Operation = {
* Example 4: Pack and unpack a message in Go
*
* foo := &pb.Foo{...}
* any, err := ptypes.MarshalAny(foo)
* any, err := anypb.New(foo)
* if err != nil {
* ...
* }
* ...
* foo := &pb.Foo{}
* if err := ptypes.UnmarshalAny(any, foo); err != nil {
* if err := any.UnmarshalTo(foo); err != nil {
* ...
* }
*
Expand Down Expand Up @@ -3803,7 +3806,16 @@ const NullValue = {
* .setNanos((int) ((millis % 1000) * 1000000)).build();
*
*
* Example 5: Compute Timestamp from current time in Python.
* Example 5: Compute Timestamp from Java `Instant.now()`.
*
* Instant now = Instant.now();
*
* Timestamp timestamp =
* Timestamp.newBuilder().setSeconds(now.getEpochSecond())
* .setNanos(now.getNano()).build();
*
*
* Example 6: Compute Timestamp from current time in Python.
*
* timestamp = Timestamp()
* timestamp.GetCurrentTime()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1272,10 +1272,13 @@ module Google
# Example 4: Pack and unpack a message in Go
#
# foo := &pb.Foo{...}
# any, err := ptypes.MarshalAny(foo)
# any, err := anypb.New(foo)
# if err != nil {
# ...
# }
# ...
# foo := &pb.Foo{}
# if err := ptypes.UnmarshalAny(any, foo); err != nil {
# if err := any.UnmarshalTo(foo); err != nil {
# ...
# }
#
Expand Down Expand Up @@ -1832,7 +1835,16 @@ module Google
# .setNanos((int) ((millis % 1000) * 1000000)).build();
#
#
# Example 5: Compute Timestamp from current time in Python.
# Example 5: Compute Timestamp from Java `Instant.now()`.
#
# Instant now = Instant.now();
#
# Timestamp timestamp =
# Timestamp.newBuilder().setSeconds(now.getEpochSecond())
# .setNanos(now.getNano()).build();
#
#
# Example 6: Compute Timestamp from current time in Python.
#
# timestamp = Timestamp()
# timestamp.GetCurrentTime()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,10 +848,13 @@ module Google
# Example 4: Pack and unpack a message in Go
#
# foo := &pb.Foo{...}
# any, err := ptypes.MarshalAny(foo)
# any, err := anypb.New(foo)
# if err != nil {
# ...
# }
# ...
# foo := &pb.Foo{}
# if err := ptypes.UnmarshalAny(any, foo); err != nil {
# if err := any.UnmarshalTo(foo); err != nil {
# ...
# }
#
Expand Down
Loading

0 comments on commit 893447f

Please sign in to comment.