in src/go/configgenerator/routegen/util.go [152:227]
func ParseHTTPPatternsBySelectorFromOPConfig(serviceConfig *servicepb.Service, opts options.ConfigGeneratorOptions) (map[string][]*httppattern.Pattern, error) {
selectors := ParseSelectorsFromOPConfig(serviceConfig, opts)
httpRuleBySelector := PrecomputeHTTPRuleBySelectorFromOPConfig(serviceConfig, opts)
selectorToJsonMappings, err := ComputeSnakeToJsonMapping(serviceConfig)
if err != nil {
return nil, fmt.Errorf("fail to compute snake_case to camelCase field mappings: %v", err)
}
httpPatternsBySelector := make(map[string][]*httppattern.Pattern)
for _, selector := range selectors {
rule, ok := httpRuleBySelector[selector]
if !ok {
continue
}
snakeToJson, ok := selectorToJsonMappings[selector]
if !ok {
// No mappings is OK.
snakeToJson = make(map[string]string)
}
pattern, err := HTTPRuleToHTTPPattern(rule, snakeToJson)
if err != nil {
return nil, fmt.Errorf("fail to process http rule for operation %q: %v", selector, err)
}
httpPatternsBySelector[selector] = append(httpPatternsBySelector[selector], pattern)
// additional_bindings cannot be nested inside themselves according to
// https://aip.dev/127. Service Management will enforce this restriction
// when interpret the http rules from the descriptor. Therefore, no need to
// check for nested additional_bindings.
for i, additionalRule := range rule.AdditionalBindings {
additionalPattern, err := HTTPRuleToHTTPPattern(additionalRule, snakeToJson)
if err != nil {
return nil, fmt.Errorf("fail to process http rule's additional_binding at index %d for operation %q: %v", i, selector, err)
}
httpPatternsBySelector[selector] = append(httpPatternsBySelector[selector], additionalPattern)
}
}
isGRPCSupportRequired, err := filtergen.IsGRPCSupportRequiredForOPConfig(serviceConfig, opts)
if err != nil {
return nil, fmt.Errorf("fail to check if gRPC support is required: %v", err)
}
if !isGRPCSupportRequired {
return httpPatternsBySelector, nil
}
// Add gRPC paths for gRPC backends.
for _, api := range serviceConfig.GetApis() {
if util.ShouldSkipOPDiscoveryAPI(api.GetName(), opts.AllowDiscoveryAPIs) {
glog.Warningf("Skip API %q because discovery API is not supported.", api.GetName())
continue
}
for _, method := range api.GetMethods() {
selector := filtergen.MethodToSelector(api, method)
gRPCPath := fmt.Sprintf("/%s/%s", api.GetName(), method.GetName())
// For the OP config generated by api compiler, the path/uri template for grpc
// method should always be valid.
uriTemplate, err := httppattern.ParseUriTemplate(gRPCPath)
if err != nil {
return nil, fmt.Errorf("error parsing auto-generated gRPC http rule's URI template for operation %q: %v", selector, err)
}
pattern := &httppattern.Pattern{
UriTemplate: uriTemplate,
HttpMethod: util.POST,
}
httpPatternsBySelector[selector] = append(httpPatternsBySelector[selector], pattern)
}
}
return httpPatternsBySelector, nil
}