<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rules

import (
	"fmt"
	"regexp"

	"github.com/googleapis/api-linter/lint"
	"github.com/googleapis/api-linter/rules/descriptor"
	p "google.golang.org/protobuf/reflect/protoreflect"
)

func init() {
	registerRules(
		checkListRequestMessageName(),
		checkListRequestMessageParentField(),
		checkListRequestMessageUnknownFields(),
		checkListResponseMessageName(),
	)
}

// List messages should have a properly named Request message.
func checkListRequestMessageName() lint.Rule {
	return &descriptor.CallbackRule{
		RuleInfo: lint.RuleInfo{
			Name:         lint.NewRuleName("core", "0132", "request_message", "name"),
			Description:  "check that List RPCs have appropriate request messages",
			RequestTypes: []lint.RequestType{lint.ProtoRequest},
			URI:          "https://aip.dev/132#guidance",
		},
		Callback: descriptor.Callbacks{
			MethodCallback: func(m p.MethodDescriptor, s lint.DescriptorSource) (problems []lint.Problem, err error) {
				// We only care about List- methods for the purpose of this rule;
				// ignore everything else.
				if !isListMethod(m) {
					return
				}

				// Rule check: Establish that for methods such as `ListFoos`, the request
				// message is named `ListFoosRequest`.
				methodName := string(m.Name())
				requestMessageName := string(m.Input().Name())
				if requestMessageName != methodName+"Request" {
					problems = append(problems, lint.Problem{
						Message: fmt.Sprintf(
							"List RPCs should have a request message named after the RPC, such as %q.",
							methodName+"Request",
						),
						Suggestion: methodName + "Request",
						Descriptor: m,
					})
				}

				return problems, nil
			},
		},
	}
}

// The List standard method should contain a parent field.
func checkListRequestMessageParentField() lint.Rule {
	return &descriptor.CallbackRule{
		RuleInfo: lint.RuleInfo{
			Name:         lint.NewRuleName("core", "0132", "request_message", "parent_field"),
			Description:  "check that a parent field is present",
			RequestTypes: []lint.RequestType{lint.ProtoRequest},
			URI:          "https://aip.dev/132#request-message",
		},
		Callback: descriptor.Callbacks{
			MethodCallback: func(m p.MethodDescriptor, s lint.DescriptorSource) (problems []lint.Problem, err error) {
				// We only care about List- methods for the purpose of this rule;
				// ignore everything else.
				if !isListMethod(m) {
					return
				}

				// Rule check: Establish that a `parent` field is present.
				parentField := m.Input().Fields().ByName("parent")
				if parentField == nil {
					problems = append(problems, lint.Problem{
						Message:    fmt.Sprintf("method %q has no `parent` field", m.Name()),
						Descriptor: m.Input(),
					})
					return problems, nil
				}

				// Rule check: Establish that the parent field is a string.
				if parentField.Kind() != p.StringKind {
					problems = append(problems, lint.Problem{
						Message:    "`parent` field on List RPCs should be a string",
						Descriptor: parentField,
					})
				}
<commit_msg>[aip-132] make message more descriptive (#108)<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rules

import (
	"fmt"
	"regexp"

	"github.com/googleapis/api-linter/lint"
	"github.com/googleapis/api-linter/rules/descriptor"
	p "google.golang.org/protobuf/reflect/protoreflect"
)

func init() {
	registerRules(
		checkListRequestMessageName(),
		checkListRequestMessageParentField(),
		checkListRequestMessageUnknownFields(),
		checkListResponseMessageName(),
	)
}

// List messages should have a properly named Request message.
func checkListRequestMessageName() lint.Rule {
	return &descriptor.CallbackRule{
		RuleInfo: lint.RuleInfo{
			Name:         lint.NewRuleName("core", "0132", "request_message", "name"),
			Description:  "check that List RPCs have appropriate request messages",
			RequestTypes: []lint.RequestType{lint.ProtoRequest},
			URI:          "https://aip.dev/132#guidance",
		},
		Callback: descriptor.Callbacks{
			MethodCallback: func(m p.MethodDescriptor, s lint.DescriptorSource) (problems []lint.Problem, err error) {
				// We only care about List- methods for the purpose of this rule;
				// ignore everything else.
				if !isListMethod(m) {
					return
				}

				// Rule check: Establish that for methods such as `ListFoos`, the request
				// message is named `ListFoosRequest`.
				methodName := string(m.Name())
				requestMessageName := string(m.Input().Name())
				if requestMessageName != methodName+"Request" {
					problems = append(problems, lint.Problem{
						Message: fmt.Sprintf(
							"List RPCs should have a request message named after the RPC, such as %q.",
							methodName+"Request",
						),
						Suggestion: methodName + "Request",
						Descriptor: m,
					})
				}

				return problems, nil
			},
		},
	}
}

// The List standard method should contain a parent field.
func checkListRequestMessageParentField() lint.Rule {
	return &descriptor.CallbackRule{
		RuleInfo: lint.RuleInfo{
			Name:         lint.NewRuleName("core", "0132", "request_message", "parent_field"),
			Description:  "check that a parent field is present",
			RequestTypes: []lint.RequestType{lint.ProtoRequest},
			URI:          "https://aip.dev/132#request-message",
		},
		Callback: descriptor.Callbacks{
			MethodCallback: func(m p.MethodDescriptor, s lint.DescriptorSource) (problems []lint.Problem, err error) {
				// We only care about List- methods for the purpose of this rule;
				// ignore everything else.
				if !isListMethod(m) {
					return
				}

				// Rule check: Establish that a `parent` field is present.
				parentField := m.Input().Fields().ByName("parent")
				if parentField == nil {
					problems = append(problems, lint.Problem{
						Message:    fmt.Sprintf("method %q input %q has no `parent` field", m.Name(), m.Input().Name()),
						Descriptor: m.Input(),
					})
					return problems, nil
				}

				// Rule check: Establish that the parent field is a string.
				if parentField.Kind() != p.StringKind {
					problems = append(problems, lint.Problem{
						Message:    "`parent` field on List RPCs should be a string",
						Descriptor: parentField,
					})
				}

{'fraction_non_alphanumeric': 0.11415275116342732, 'fraction_numerical': 0.00684369011771147, 'mean_word_length': 3.333926453143535, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2074165', 'n_tokens_mistral': 2535, 'n_tokens_neox': 2065, 'n_words': 672}