use of com.google.api.generator.gapic.model.ResourceName in project gapic-generator-java by googleapis.
the class MethodSignatureParser method parseTypeFromArgumentName.
private static Map<TypeNode, Field> parseTypeFromArgumentName(String argumentName, String servicePackage, Message inputMessage, Map<String, Message> messageTypes, Map<String, ResourceName> resourceNames, Map<String, ResourceName> patternsToResourceNames, List<Field> argumentFieldPathAcc, Set<ResourceName> outputArgResourceNames) {
Map<TypeNode, Field> typeToField = new HashMap<>();
int dotIndex = argumentName.indexOf(DOT);
if (dotIndex < 1) {
Field field = inputMessage.fieldMap().get(argumentName);
Preconditions.checkNotNull(field, String.format("Field %s not found from input message %s values %s", argumentName, inputMessage.name(), inputMessage.fieldMap().keySet()));
if (!field.hasResourceReference()) {
typeToField.put(field.type(), field);
return typeToField;
}
// Parse the resource name tyeps.
List<ResourceName> resourceNameArgs = ResourceReferenceParser.parseResourceNames(field.resourceReference(), servicePackage, field.description(), resourceNames, patternsToResourceNames);
outputArgResourceNames.addAll(resourceNameArgs);
typeToField.put(TypeNode.STRING, field);
typeToField.putAll(resourceNameArgs.stream().collect(Collectors.toMap(r -> r.type(), r -> field.toBuilder().setResourceReference(ResourceReference.withType(r.resourceTypeString())).build())));
// Only resource name helpers should have more than one entry.
if (typeToField.size() > 1) {
typeToField.entrySet().stream().forEach(e -> {
// Skip string-only variants or ResourceName generics.
if (e.getKey().equals(TypeNode.STRING) || e.getKey().reference().name().equals("ResourceName")) {
return;
}
String resourceJavaTypeName = e.getKey().reference().name();
String resourceTypeName = e.getValue().resourceReference().resourceTypeString();
int indexOfSlash = resourceTypeName.indexOf("/");
// We assume that the corresponding Java resource name helper type (i.e. the key)
// ends in *Name. Check that it matches the expeced resource name type.
Preconditions.checkState(resourceJavaTypeName.substring(0, resourceJavaTypeName.length() - 4).equals(resourceTypeName.substring(indexOfSlash + 1)), String.format("Resource Java type %s does not correspond to proto type %s", resourceJavaTypeName, resourceTypeName));
});
}
return typeToField;
}
Preconditions.checkState(dotIndex < argumentName.length() - 1, String.format("Invalid argument name found: dot cannot be at the end of name %s", argumentName));
String firstFieldName = argumentName.substring(0, dotIndex);
String remainingArgumentName = argumentName.substring(dotIndex + 1);
// Must be a sub-message for a type's subfield to be valid.
Field firstField = inputMessage.fieldMap().get(firstFieldName);
// Validate the field into which we're descending.
Preconditions.checkState(!firstField.isRepeated(), String.format("Cannot descend into repeated field %s", firstField.name()));
TypeNode firstFieldType = firstField.type();
Preconditions.checkState(TypeNode.isReferenceType(firstFieldType) && !firstFieldType.equals(TypeNode.STRING), String.format("Field reference on %s cannot be a primitive type", firstFieldName));
String firstFieldTypeName = firstFieldType.reference().fullName();
Message firstFieldMessage = messageTypes.get(firstFieldTypeName);
Preconditions.checkNotNull(firstFieldMessage, String.format("Message type %s for field reference %s invalid", firstFieldTypeName, firstFieldName));
argumentFieldPathAcc.add(firstField);
return parseTypeFromArgumentName(remainingArgumentName, servicePackage, firstFieldMessage, messageTypes, resourceNames, patternsToResourceNames, argumentFieldPathAcc, outputArgResourceNames);
}
use of com.google.api.generator.gapic.model.ResourceName in project gapic-generator-java by googleapis.
the class Parser method updateResourceNamesInMessages.
/**
* Populates ResourceName objects in Message POJOs.
*
* @param messageTypes A map of the message type name (as in the protobuf) to Message POJOs.
* @param resources A list of ResourceName POJOs.
* @return The updated messageTypes map.
*/
public static Map<String, Message> updateResourceNamesInMessages(Map<String, Message> messageTypes, Collection<ResourceName> resources) {
Map<String, Message> updatedMessages = new HashMap<>(messageTypes);
for (ResourceName resource : resources) {
if (!resource.hasParentMessageName()) {
continue;
}
String messageKey = resource.parentMessageName();
Message messageToUpdate = updatedMessages.get(messageKey);
updatedMessages.put(messageKey, messageToUpdate.toBuilder().setResource(resource).build());
}
return updatedMessages;
}
use of com.google.api.generator.gapic.model.ResourceName in project gapic-generator-java by googleapis.
the class Parser method parseMethods.
@VisibleForTesting
static List<Method> parseMethods(ServiceDescriptor serviceDescriptor, String servicePackage, Map<String, Message> messageTypes, Map<String, ResourceName> resourceNames, Optional<GapicServiceConfig> serviceConfigOpt, Set<ResourceName> outputArgResourceNames, Transport transport) {
List<Method> methods = new ArrayList<>();
for (MethodDescriptor protoMethod : serviceDescriptor.getMethods()) {
// Parse the method.
TypeNode inputType = TypeParser.parseType(protoMethod.getInputType());
Method.Builder methodBuilder = Method.builder();
if (protoMethod.getFile().toProto().hasSourceCodeInfo()) {
SourceCodeInfoLocation protoMethodLocation = SOURCE_CODE_INFO_PARSER.getLocation(protoMethod);
if (!Objects.isNull(protoMethodLocation) && !Strings.isNullOrEmpty(protoMethodLocation.getLeadingComments())) {
methodBuilder.setDescription(protoMethodLocation.getLeadingComments());
}
}
boolean isDeprecated = false;
if (protoMethod.getOptions().hasDeprecated()) {
isDeprecated = protoMethod.getOptions().getDeprecated();
}
Message inputMessage = messageTypes.get(inputType.reference().fullName());
Preconditions.checkNotNull(inputMessage, String.format("No message found for %s", inputType.reference().fullName()));
HttpBindings httpBindings = HttpRuleParser.parse(protoMethod, inputMessage, messageTypes);
boolean isBatching = !serviceConfigOpt.isPresent() ? false : serviceConfigOpt.get().hasBatchingSetting(/* protoPakkage */
protoMethod.getFile().getPackage(), serviceDescriptor.getName(), protoMethod.getName());
boolean operationPollingMethod = protoMethod.getOptions().hasExtension(ExtendedOperationsProto.operationPollingMethod) ? protoMethod.getOptions().getExtension(ExtendedOperationsProto.operationPollingMethod) : false;
RoutingHeaderRule routingHeaderRule = RoutingRuleParser.parse(protoMethod, inputMessage, messageTypes);
methods.add(methodBuilder.setName(protoMethod.getName()).setInputType(inputType).setOutputType(TypeParser.parseType(protoMethod.getOutputType())).setStream(Method.toStream(protoMethod.isClientStreaming(), protoMethod.isServerStreaming())).setLro(parseLro(servicePackage, protoMethod, messageTypes)).setMethodSignatures(MethodSignatureParser.parseMethodSignatures(protoMethod, servicePackage, inputType, messageTypes, resourceNames, outputArgResourceNames)).setHttpBindings(httpBindings).setRoutingHeaderRule(routingHeaderRule).setIsBatching(isBatching).setPageSizeFieldName(parsePageSizeFieldName(protoMethod, messageTypes, transport)).setIsDeprecated(isDeprecated).setOperationPollingMethod(operationPollingMethod).build());
// Any input type that has a resource reference will need a resource name helper class.
for (Field field : inputMessage.fields()) {
if (field.hasResourceReference()) {
String resourceTypeString = field.resourceReference().resourceTypeString();
ResourceName resourceName = null;
// versus example.com/FooBar.
if (resourceTypeString.indexOf(SLASH) < 0) {
Optional<String> actualResourceTypeNameOpt = resourceNames.keySet().stream().filter(k -> k.substring(k.lastIndexOf(SLASH) + 1).equals(resourceTypeString)).findFirst();
if (actualResourceTypeNameOpt.isPresent()) {
resourceName = resourceNames.get(actualResourceTypeNameOpt.get());
}
} else {
resourceName = resourceNames.get(resourceTypeString);
}
if (ResourceNameConstants.WILDCARD_PATTERN.equals(resourceTypeString)) {
resourceName = WILDCARD_RESOURCE_NAME;
} else {
Preconditions.checkNotNull(resourceName, String.format("Resource name %s not found; parsing field %s in message %s in method %s", resourceTypeString, field.name(), inputMessage.name(), protoMethod.getName()));
}
outputArgResourceNames.add(resourceName);
}
}
}
return methods;
}
use of com.google.api.generator.gapic.model.ResourceName in project gapic-generator-java by googleapis.
the class ParserTest method parseMethodSignatures_validArgstAndEmptyString.
@Test
public void parseMethodSignatures_validArgstAndEmptyString() {
// TODO(miraleung): Move this to MethodSignatureParserTest.
MethodDescriptor methodDescriptor = echoService.getMethods().get(0);
assertEquals("Echo", methodDescriptor.getName());
TypeNode inputType = TypeParser.parseType(methodDescriptor.getInputType());
Map<String, Message> messageTypes = Parser.parseMessages(echoFileDescriptor);
Map<String, ResourceName> resourceNames = Parser.parseResourceNames(echoFileDescriptor);
Set<ResourceName> outputResourceNames = new HashSet<>();
List<List<MethodArgument>> methodArgs = MethodSignatureParser.parseMethodSignatures(methodDescriptor, ECHO_PACKAGE, inputType, messageTypes, resourceNames, outputResourceNames);
assertEquals(Collections.emptyList(), methodArgs.get(0));
assertEquals(1, methodArgs.get(1).size());
assertEquals("parent", methodArgs.get(1).get(0).name());
}
use of com.google.api.generator.gapic.model.ResourceName in project gapic-generator-java by googleapis.
the class ParserTest method parseResourceNames_inputTypeHasReferenceNotInMethodSignature.
@Test
public void parseResourceNames_inputTypeHasReferenceNotInMethodSignature() {
FileDescriptor testingFileDescriptor = TestingOuterClass.getDescriptor();
ServiceDescriptor testingService = testingFileDescriptor.getServices().get(0);
assertEquals(testingService.getName(), "Testing");
Map<String, Message> messageTypes = Parser.parseMessages(testingFileDescriptor);
Map<String, ResourceName> resourceNames = Parser.parseResourceNames(testingFileDescriptor);
Set<ResourceName> outputResourceNames = new HashSet<>();
Parser.parseService(testingFileDescriptor, messageTypes, resourceNames, Optional.empty(), outputResourceNames);
assertEquals(2, outputResourceNames.size());
ResourceName resname = resourceNames.get("showcase.googleapis.com/Session");
assertThat(outputResourceNames).contains(resname);
resname = resourceNames.get("showcase.googleapis.com/Test");
assertThat(outputResourceNames).contains(resname);
}
Aggregations