func ParseHTTPPatternsBySelectorFromOPConfig()

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
}