Skip to content

Commit

Permalink
WIP - some tempalte changes
Browse files Browse the repository at this point in the history
  • Loading branch information
leahecole committed Oct 18, 2024
1 parent bb6e476 commit 8c5dd23
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 9 deletions.
17 changes: 17 additions & 0 deletions templates/cjs/typescript_gapic/_util.njk
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,24 @@ limitations under the License.
{%- for oneComment in commentsMap -%}
{%- set type = oneComment.paramType -%}
{%- if type.startsWith('.') %}
{# TODO: coleleah - add logic here for if it's maxResults paramter allow a number too #}
{# method allows wrappers
is a paginated call not async or stream
the paramter here is max_results
it's a uint32 #}
{# {{ generatedName | dump }}
{%- if method.maxResultsParameter and type == ".google.protobuf.UInt32Value" and method.pagingResponseType and printRequestField(oneComment)=="request.maxResults"%}
// pepperoni
* @param { {{- type.substring(1) -}} | number } {{ printRequestField(oneComment) }}
{%- else %} #}

* @param { {{- type.substring(1) -}} } {{ printRequestField(oneComment) }}
{# {%- endif -%} #}




{%- else %}
* @param { {{- convertParamType(oneComment.paramType) -}} } {{ printRequestField(oneComment) }}
{%- endif -%}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ export class {{ service.name }}Client {
}
{%- endfor %}
{%- for method in service.paging %}

{%- if not method.ignoreMapPagingMethod %}
{%- if not method.pagingMapResponseType %}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,15 @@ export class {{ service.name }}Client {
{{ util.toInterface(method.outputInterface) }}
]>|void {
request = request || {};
{%- if method.maxResultsParameter %}
// the underlying API expects a UInt32Value object
// users can pass this directly, but if they have passed a number as they
// would for an AIP compliant paginated call, convert if for them
if(request.maxResults && typeof request.maxResults === "number"){
const maxResultsObject = {"value": request.maxResults}
request.maxResults = maxResultsObject
}
{%- endif %}
{%- for field in method.autoPopulatedFields %}
if (!request.{{ field.toCamelCase() }}) {
request.{{ field.toCamelCase() }} = gax.makeUUID();
Expand Down
15 changes: 7 additions & 8 deletions typescript/src/schema/proto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const COMMON_PROTO_LIST = [
'google.type',
];

// services that are allowed to use UInt32Value protobuf wrapper types
// services that are allowed to use Int32Value and UInt32Value protobuf wrapper types

Check failure on line 38 in typescript/src/schema/proto.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `··//·services·that·are·allowed·to·use·Int32Value·and·UInt32Value·protobuf·wrapper·types·` with `//·services·that·are·allowed·to·use·Int32Value·and·UInt32Value·protobuf·wrapper·types`

Check failure on line 38 in typescript/src/schema/proto.ts

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
// instead of "number" for pageSize/maxResults

Check failure on line 39 in typescript/src/schema/proto.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `··`
// keyed by proto package name, e.g. "google.cloud.foo.v1".

Check failure on line 40 in typescript/src/schema/proto.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `··`
const ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE = {

Check failure on line 41 in typescript/src/schema/proto.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `··`
Expand Down Expand Up @@ -274,9 +274,10 @@ function streaming(method: MethodDescriptorProto) {
return undefined;
}

// TODO docstring
// TODO can this be in paging field? maybe? unclear
function getMaxResultsParameter(messages, method, wrappersAllowed){
// returns true if the method has wrappers for UInt32Value enabled
// and is a paginated call with a maxResults parameter instead of pageSize
// as of its creation, this should only be true for BigQuery
function wrappersHasMaxResultsParameter(messages, method, wrappersAllowed){

Check failure on line 280 in typescript/src/schema/proto.ts

View workflow job for this annotation

GitHub Actions / lint

Insert `·`
const inputType = messages[method.inputType!];
const hasMaxResults =
inputType &&
Expand All @@ -302,8 +303,6 @@ function pagingField(
// next version.
//
// This should not be done for any other API.
// TODO(coleleah): update this to include bigquery and except GetQueryResults
// TODO remember why I wrote teh above comment
const serviceNameException =
service && service.packageName === 'google.cloud.talent.v4beta1';
const methodNameException =
Expand Down Expand Up @@ -543,7 +542,7 @@ function augmentMethod(
parameters: AugmentMethodParameters,
method: MethodDescriptorProto
) {
// whether a service is allowed to use UInt32Value wrappers - generally this is only BigQuery
// whether a service is allowed to use Int32Value and UInt32Value wrappers - generally this is only BigQuery
// this is used to determine factors about pagination fields and to allow users to pass a "number" instead of
// having to convert to a protobuf wrapper type to determine page size
const wrappersAllowed = ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE[parameters.service.packageName];
Expand Down Expand Up @@ -604,7 +603,7 @@ function augmentMethod(
),
retryableCodesName: defaultNonIdempotentRetryCodesName,
retryParamsName: defaultParametersName,
maxResultsParameter: getMaxResultsParameter(parameters.allMessages, method, wrappersAllowed)
maxResultsParameter: wrappersHasMaxResultsParameter(parameters.allMessages, method, wrappersAllowed)
},
method
) as MethodDescriptorProto;
Expand Down
157 changes: 156 additions & 1 deletion typescript/test/unit/proto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,7 @@ describe('src/schema/proto.ts', () => {
'.google.cloud.showcase.v1beta1.Address'
);
});
it('should not be page field if api is not google discovery api but use "max_result"', () => {
it('should not be page field if api is not google discovery api, method is not allowlisted, but use "max_result"', () => {
const fd = {} as protos.google.protobuf.FileDescriptorProto;
fd.name = 'google/cloud/showcase/v1beta1/test.proto';
fd.package = 'google.cloud.showcase.v1beta1';
Expand Down Expand Up @@ -1239,5 +1239,160 @@ describe('src/schema/proto.ts', () => {
);
assert.deepStrictEqual(proto.services['service'].paging.length, 0);
});

});
describe('should support pagination for allowlisted APIs that use UInt32 wrappers and max_results', () => {
it('should be page field if allowlisted with wrappers and use "max_results" as field name', () => {
const fd = {} as protos.google.protobuf.FileDescriptorProto;
fd.name = 'google/cloud/bigquery/v2/cats.proto';
// bq is the only service where this behavior is currently allowlisted
fd.package = 'google.cloud.bigquery.v2';
fd.service = [{} as protos.google.protobuf.ServiceDescriptorProto];
fd.service[0].name = 'CatService';
fd.service[0].method = [
{} as protos.google.protobuf.MethodDescriptorProto,
];
fd.service[0].method[0] =
{} as protos.google.protobuf.MethodDescriptorProto;
fd.service[0].method[0].name = 'ListCats';
fd.service[0].method[0].outputType =
'.google.cloud.bigquery.v2.CatList';
fd.service[0].method[0].inputType =
'.google.cloud.bigquery.v2.ListCatsRequest';

fd.messageType = [{} as protos.google.protobuf.DescriptorProto];
fd.messageType[0] = {} as protos.google.protobuf.DescriptorProto;
fd.messageType[1] = {} as protos.google.protobuf.DescriptorProto;

fd.messageType[0].name = 'CatList';
fd.messageType[1].name = 'ListCatsRequest';

fd.messageType[0].field = [
{} as protos.google.protobuf.FieldDescriptorProto,
];
fd.messageType[0].field[0] =
{} as protos.google.protobuf.FieldDescriptorProto;
fd.messageType[0].field[0].name = 'next_page_token';
fd.messageType[0].field[0].label = 3; // LABEL_REPEATED
fd.messageType[0].field[0].type = 11; // TYPE_MESSAGE
fd.messageType[0].field[0].typeName =
'.google.cloud.bigquery.v2.Cat';
fd.messageType[1].field = [
{} as protos.google.protobuf.FieldDescriptorProto,
];
fd.messageType[1].field[0] =
{} as protos.google.protobuf.FieldDescriptorProto;
fd.messageType[1].field[0].name = 'max_results';
fd.messageType[1].field[1] =
{} as protos.google.protobuf.FieldDescriptorProto;
fd.messageType[1].field[1].name = 'page_token';
const options: Options = {
grpcServiceConfig: {} as protos.grpc.service_config.ServiceConfig,
diregapic: false,
};
const allMessages: MessagesMap = {};
fd.messageType
?.filter(message => message.name)
.forEach(message => {
allMessages['.' + fd.package! + '.' + message.name!] = message;
});
const commentsMap = new CommentsMap([fd]);
const proto = new Proto({
fd,
packageName: 'google.cloud.bigquery.v2',
allMessages,
allResourceDatabase: new ResourceDatabase(),
resourceDatabase: new ResourceDatabase(),
options,
commentsMap,
});
assert.deepStrictEqual(
proto.services['CatService'].method[0].pagingFieldName,
'next_page_token'
);
assert.deepStrictEqual(proto.services['CatService'].paging[0].name, 'ListCats');
assert.deepStrictEqual(
proto.services['CatService'].paging[0].inputType,
'.google.cloud.bigquery.v2.ListCatsRequest'
);
assert.deepStrictEqual(
proto.services['CatService'].paging[0].outputType,
'.google.cloud.bigquery.v2.CatList'
);
assert.deepStrictEqual(
proto.services['CatService'].paging[0].pagingResponseType,
'.google.cloud.bigquery.v2.Cat'
);
});
it('should not be page field if api is not google discovery api, is not wrappers allowed but uses "max_result"', () => {
const fd = {} as protos.google.protobuf.FileDescriptorProto;
fd.name = 'google/cloud/felines/v2/cats.proto';
// bq is the only service where this behavior is currently allowlisted
fd.package = 'google.cloud.felines.v2';
fd.service = [{} as protos.google.protobuf.ServiceDescriptorProto];
fd.service[0].name = 'CatService';
fd.service[0].method = [
{} as protos.google.protobuf.MethodDescriptorProto,
];
fd.service[0].method[0] =
{} as protos.google.protobuf.MethodDescriptorProto;
fd.service[0].method[0].name = 'ListCats';
fd.service[0].method[0].outputType =
'.google.cloud.felines.v2.CatList';
fd.service[0].method[0].inputType =
'.google.cloud.felines.v2.ListCatsRequest';

fd.messageType = [{} as protos.google.protobuf.DescriptorProto];
fd.messageType[0] = {} as protos.google.protobuf.DescriptorProto;
fd.messageType[1] = {} as protos.google.protobuf.DescriptorProto;

fd.messageType[0].name = 'CatList';
fd.messageType[1].name = 'ListCatsRequest';

fd.messageType[0].field = [
{} as protos.google.protobuf.FieldDescriptorProto,
];
fd.messageType[0].field[0] =
{} as protos.google.protobuf.FieldDescriptorProto;
fd.messageType[0].field[0].name = 'next_page_token';
fd.messageType[0].field[0].label = 3; // LABEL_REPEATED
fd.messageType[0].field[0].type = 11; // TYPE_MESSAGE
fd.messageType[0].field[0].typeName =
'.google.cloud.bigquery.v2.Cat';
fd.messageType[1].field = [
{} as protos.google.protobuf.FieldDescriptorProto,
];
fd.messageType[1].field[0] =
{} as protos.google.protobuf.FieldDescriptorProto;
fd.messageType[1].field[0].name = 'max_results';
fd.messageType[1].field[1] =
{} as protos.google.protobuf.FieldDescriptorProto;
fd.messageType[1].field[1].name = 'page_token';
const options: Options = {
grpcServiceConfig: {} as protos.grpc.service_config.ServiceConfig,
diregapic: false,
};
const allMessages: MessagesMap = {};
fd.messageType
?.filter(message => message.name)
.forEach(message => {
allMessages['.' + fd.package! + '.' + message.name!] = message;
});
const commentsMap = new CommentsMap([fd]);
const proto = new Proto({
fd,
packageName: 'google.cloud.felines.v2',
allMessages,
allResourceDatabase: new ResourceDatabase(),
resourceDatabase: new ResourceDatabase(),
options,
commentsMap,
});
assert.deepStrictEqual(
proto.services['CatService'].method[0].pagingFieldName,
undefined
);
assert.deepStrictEqual(proto.services['CatService'].paging.length, 0);
});
});
});

0 comments on commit 8c5dd23

Please sign in to comment.