Skip to content

Commit

Permalink
fix: empty request params (#430)
Browse files Browse the repository at this point in the history
* fix empty request params

* construct comments map from api

* update baseline

* lint
  • Loading branch information
xiaozhenliu-gg5 authored Apr 21, 2020
1 parent f53a0f2 commit f398151
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 106 deletions.
28 changes: 22 additions & 6 deletions baselines/tasks/src/v2/cloud_tasks_client.ts.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -863,8 +863,12 @@ export class CloudTasksClient {
*
* @param {Object} request
* The request object that will be sent.
* @param {} request.
* @param {} request.
* @param {string} request.resource
* REQUIRED: The resource for which the policy is being requested.
* See the operation documentation for the appropriate value for this field.
* @param {google.iam.v1.GetPolicyOptions} request.options
* OPTIONAL: A `GetPolicyOptions` object for specifying options to
* `GetIamPolicy`. This field is only used by Cloud IAM.
* @param {object} [options]
* Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
* @returns {Promise} - The promise which resolves to an array.
Expand Down Expand Up @@ -940,8 +944,14 @@ export class CloudTasksClient {
*
* @param {Object} request
* The request object that will be sent.
* @param {} request.
* @param {} request.
* @param {string} request.resource
* REQUIRED: The resource for which the policy is being specified.
* See the operation documentation for the appropriate value for this field.
* @param {google.iam.v1.Policy} request.policy
* REQUIRED: The complete policy to be applied to the `resource`. The size of
* the policy is limited to a few 10s of KB. An empty policy is a
* valid policy but certain Cloud Platform services (such as Projects)
* might reject them.
* @param {object} [options]
* Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
* @returns {Promise} - The promise which resolves to an array.
Expand Down Expand Up @@ -1013,8 +1023,14 @@ export class CloudTasksClient {
*
* @param {Object} request
* The request object that will be sent.
* @param {} request.
* @param {} request.
* @param {string} request.resource
* REQUIRED: The resource for which the policy detail is being requested.
* See the operation documentation for the appropriate value for this field.
* @param {string[]} request.permissions
* The set of permissions to check for the `resource`. Permissions with
* wildcards (such as '*' or 'storage.*') are not allowed. For more
* information see
* [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions).
* @param {object} [options]
* Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details.
* @returns {Promise} - The promise which resolves to an array.
Expand Down
3 changes: 3 additions & 0 deletions typescript/src/schema/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as plugin from '../../../pbjs-genfiles/plugin';
import {Naming, Options as namingOptions} from './naming';
import {Proto, MessagesMap} from './proto';
import {ResourceDatabase, ResourceDescriptor} from './resource-database';
import {CommentsMap} from './comments';

export interface ProtosMap {
[filename: string]: Proto;
Expand Down Expand Up @@ -72,6 +73,7 @@ export class API {
allMessages['.' + fd.package! + '.' + message.name!] = message;
});
}
const commentsMap = new CommentsMap(fileDescriptors);

this.protos = fileDescriptors
.filter(fd => fd.name)
Expand All @@ -84,6 +86,7 @@ export class API {
allResourceDatabase,
resourceDatabase,
options,
commentsMap,
});
return map;
}, {} as ProtosMap);
Expand Down
201 changes: 103 additions & 98 deletions typescript/src/schema/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,115 +34,120 @@ export interface Comments {
export class CommentsMap {
comments: Comments = {};

constructor(fd: plugin.google.protobuf.IFileDescriptorProto) {
constructor(fds: plugin.google.protobuf.IFileDescriptorProto[]) {
const commentsMap: Comments = {};
if (fd && fd.sourceCodeInfo && fd.sourceCodeInfo.location) {
const locations = fd.sourceCodeInfo.location;
locations.forEach(location => {
if (location.leadingComments !== null) {
// p is an array with format [f1, i1, f2, i2, ...]
// - f1 refers to the protobuf field tag
// - if field refer to by f1 is a slice, i1 refers to an element in that slice
// - f2 and i2 works recursively.
// So, [6, x] refers to the xth service defined in the file,
// since the field tag of Service is 6.
// [6, x, 2, y] refers to the yth method in that service,
// since the field tag of Method is 2.
const p = location.path!;
if (p.length === 2 && p[0] === 6) {
if (fd.service && fd.service[p[1]] && fd.service[p[1]].name) {
const serviceName = fd.service[p[1]].name!;
const comments = (location.leadingComments || '')
.split('\n')
.slice(0, -1);
const serviceComment: Comment = {
paramName: '',
paramType: '',
comments,
};
commentsMap[serviceName] = serviceComment;
}
} else if (p.length === 4 && p[2] === 2 && p[0] === 6) {
if (
fd.service &&
fd.service[p[1]] &&
fd.service[p[1]].method &&
fd.service[p[1]].method![p[3]] &&
fd.service[p[1]].method![p[3]].name
) {
const serviceName = fd.service[p[1]].name!;
// add method comment into the map
const methodName = fd.service[p[1]].method![p[3]].name!;
if (!commentsMap[methodName]) {
const comments = (location.leadingComments || '').split('\n');
const key = serviceName + ':' + methodName;
const methodComment: Comment = {
for (const fd of fds) {
if (fd && fd.sourceCodeInfo && fd.sourceCodeInfo.location) {
const locations = fd.sourceCodeInfo.location;
locations.forEach(location => {
if (location.leadingComments !== null) {
// p is an array with format [f1, i1, f2, i2, ...]
// - f1 refers to the protobuf field tag
// - if field refer to by f1 is a slice, i1 refers to an element in that slice
// - f2 and i2 works recursively.
// So, [6, x] refers to the xth service defined in the file,
// since the field tag of Service is 6.
// [6, x, 2, y] refers to the yth method in that service,
// since the field tag of Method is 2.
const p = location.path!;
if (p.length === 2 && p[0] === 6) {
if (fd.service && fd.service[p[1]] && fd.service[p[1]].name) {
const serviceName = fd.service[p[1]].name!;
const comments = (location.leadingComments || '')
.split('\n')
.slice(0, -1);
const serviceComment: Comment = {
paramName: '',
paramType: '',
comments,
};
commentsMap[key] = methodComment;
commentsMap[serviceName] = serviceComment;
}
}
} else if (p.length === 4 && p[0] === 4 && p[2] === 2) {
// This contains a field's information
// example, this path:
// [ 4, 3, 2, 7, 1 ]
// refers to:
// file.message_type(3) // 4, 3
// .field(7) // 2, 7
// .name() // 1
// This is because FileDescriptorProto.message_type has field number 4:
// repeated DescriptorProto message_type = 4;
// and DescriptorProto.field has field number 2:
// repeated FieldDescriptorProto field = 2;
// and FieldDescriptorProto.name has field number 1:
// optional string name = 1;
if (
fd.messageType &&
fd.messageType[p[1]] &&
fd.messageType[p[1]].field &&
fd.messageType[p[1]].field![p[3]]
) {
const messageType = fd.messageType[p[1]].name;
const field = fd.messageType[p[1]].field![p[3]];
if (field) {
//Type Enum: TYPE_STRING, TYPE_BOOL, etc.
let paramType =
plugin.google.protobuf.FieldDescriptorProto.Type[field.type!];
// If field.label is 'REPEATED' then the paramType is an array.
if (field.label === 3) {
paramType += '[]';
}
const paramName = field.name || '';
if (
paramType === 'TYPE_MESSAGE' ||
paramType === 'TYPE_ENUM' ||
paramType === 'TYPE_GROUP'
) {
paramType = field.typeName!;
} else if (p.length === 4 && p[2] === 2 && p[0] === 6) {
if (
fd.service &&
fd.service[p[1]] &&
fd.service[p[1]].method &&
fd.service[p[1]].method![p[3]] &&
fd.service[p[1]].method![p[3]].name
) {
const serviceName = fd.service[p[1]].name!;
// add method comment into the map
const methodName = fd.service[p[1]].method![p[3]].name!;
if (!commentsMap[methodName]) {
const comments = (location.leadingComments || '').split('\n');
const key = serviceName + ':' + methodName;
const methodComment: Comment = {
paramName: '',
paramType: '',
comments,
};
commentsMap[key] = methodComment;
}
const comments = (location.leadingComments || '')
.split('\n')
.slice(0, -1);
const options = field.options;
const fieldComment: Comment = {
paramName,
paramType,
comments,
};
if (options && options['.google.api.fieldBehavior']) {
const fieldBehavior = options['.google.api.fieldBehavior'][0];
fieldComment.fieldBehavior = fieldBehavior;
}
} else if (p.length === 4 && p[0] === 4 && p[2] === 2) {
// This contains a field's information
// example, this path:
// [ 4, 3, 2, 7, 1 ]
// refers to:
// file.message_type(3) // 4, 3
// .field(7) // 2, 7
// .name() // 1
// This is because FileDescriptorProto.message_type has field number 4:
// repeated DescriptorProto message_type = 4;
// and DescriptorProto.field has field number 2:
// repeated FieldDescriptorProto field = 2;
// and FieldDescriptorProto.name has field number 1:
// optional string name = 1;
if (
fd.messageType &&
fd.messageType[p[1]] &&
fd.messageType[p[1]].field &&
fd.messageType[p[1]].field![p[3]]
) {
const messageType = fd.messageType[p[1]].name;
const field = fd.messageType[p[1]].field![p[3]];
if (field) {
//Type Enum: TYPE_STRING, TYPE_BOOL, etc.
let paramType =
plugin.google.protobuf.FieldDescriptorProto.Type[
field.type!
];
// If field.label is 'REPEATED' then the paramType is an array.
if (field.label === 3) {
paramType += '[]';
}
const paramName = field.name || '';
if (
paramType === 'TYPE_MESSAGE' ||
paramType === 'TYPE_ENUM' ||
paramType === 'TYPE_GROUP'
) {
paramType = field.typeName!;
}
const comments = (location.leadingComments || '')
.split('\n')
.slice(0, -1);
const options = field.options;
const fieldComment: Comment = {
paramName,
paramType,
comments,
};
if (options && options['.google.api.fieldBehavior']) {
const fieldBehavior =
options['.google.api.fieldBehavior'][0];
fieldComment.fieldBehavior = fieldBehavior;
}
const key = messageType + ':' + field.name;
commentsMap[key] = fieldComment;
}
const key = messageType + ':' + field.name;
commentsMap[key] = fieldComment;
}
}
}
}
});
this.comments = commentsMap;
});
this.comments = commentsMap;
}
}
}
getCommentsMap() {
Expand Down
4 changes: 2 additions & 2 deletions typescript/src/schema/proto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ interface ProtoParameters {
allResourceDatabase: ResourceDatabase;
resourceDatabase: ResourceDatabase;
options: Options;
commentsMap: CommentsMap;
}

export class Proto {
Expand Down Expand Up @@ -614,7 +615,6 @@ export class Proto {
this.fileToGenerate = parameters.fd.package
? parameters.fd.package.startsWith(parameters.packageName)
: false;
const commentsMap = new CommentsMap(parameters.fd);
this.services = parameters.fd.service
.filter(service => service.name)
.map(service =>
Expand All @@ -623,7 +623,7 @@ export class Proto {
localMessages: this.localMessages,
packageName: parameters.packageName,
service,
commentsMap,
commentsMap: parameters.commentsMap,
allResourceDatabase: parameters.allResourceDatabase,
resourceDatabase: parameters.resourceDatabase,
options: parameters.options,
Expand Down
3 changes: 3 additions & 0 deletions typescript/test/unit/proto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {Proto} from '../../src/schema/proto';
import {Options} from '../../src/schema/naming';

import {ResourceDatabase} from '../../src/schema/resource-database';
import {CommentsMap} from '../../src/schema/comments';

describe('src/schema/proto.ts', () => {
describe('should get header parameters from http rule', () => {
Expand Down Expand Up @@ -148,13 +149,15 @@ describe('src/schema/proto.ts', () => {
.forEach(message => {
allMessages['.' + fd.package! + '.' + message.name!] = message;
});
const commentsMap = new CommentsMap([fd]);
const proto = new Proto({
fd,
packageName: 'google.cloud.talent.v4beta1',
allMessages,
allResourceDatabase: new ResourceDatabase(),
resourceDatabase: new ResourceDatabase(),
options,
commentsMap,
});
assert.deepStrictEqual(
proto.services['service'].method[0].pagingFieldName,
Expand Down

0 comments on commit f398151

Please sign in to comment.