diff --git a/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/message.proto b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/message.proto new file mode 100644 index 00000000..3917a2a6 --- /dev/null +++ b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/message.proto @@ -0,0 +1,60 @@ +// Copyright 2021 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 +// +// http://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. +// + +syntax = "proto3"; + +package tests.lintercomments.message.v1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/google/gnostic/apps/protoc-gen-openapi/examples/tests/lintercomments/message/v1;message"; + +// Test service for linter comment filtering +service Messaging { + rpc CreateMessage(Message) returns (Response) { + option (google.api.http) = { + post : "/v1/messages" + body : "*" + }; + } +} + +// Message demonstrates linter comment filtering in descriptions +message Message { + // (-- api-linter: core::0122::name-suffix=disabled + // aip.dev/not-precedent: We use a different naming convention. --) + // This field has a single-line linter comment that should be filtered out. + // This comment should remain visible. + string field_with_single_line_comment = 1; + + // (-- api-linter: core::0133::request-unknown-fields=disabled + // aip.dev/not-precedent: This field is needed to deduplicate asset + // registration. --) + // This field has a multi-line linter comment that should be filtered out. + // This comment should remain visible. + string field_with_multiline_comment = 2; + + // Normal field without any linter comments. + // This entire comment should remain visible. + string normal_field = 3; +} + +// Response message +message Response { + // (-- api-linter: core::0158::response-next-page-token-field=disabled + // aip.dev/not-precedent: We have a different pagination scheme. --) + // Response field with linter comment. + string result = 1; +} diff --git a/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_json/Message.json b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_json/Message.json new file mode 100644 index 00000000..0dcc2883 --- /dev/null +++ b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_json/Message.json @@ -0,0 +1,24 @@ +{ + "title": "Message", + "$id": "http://example.com/schemas/Message.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "Message demonstrates linter comment filtering in descriptions", + "properties": { + "fieldWithSingleLineComment": { + "title": "fieldWithSingleLineComment", + "type": "string", + "description": "This field has a single-line linter comment that should be filtered out. This comment should remain visible." + }, + "fieldWithMultilineComment": { + "title": "fieldWithMultilineComment", + "type": "string", + "description": "This field has a multi-line linter comment that should be filtered out. This comment should remain visible." + }, + "normalField": { + "title": "normalField", + "type": "string", + "description": "Normal field without any linter comments. This entire comment should remain visible." + } + } +} diff --git a/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_json/Response.json b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_json/Response.json new file mode 100644 index 00000000..7950e1e3 --- /dev/null +++ b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_json/Response.json @@ -0,0 +1,14 @@ +{ + "title": "Response", + "$id": "http://example.com/schemas/Response.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "Response message", + "properties": { + "result": { + "title": "result", + "type": "string", + "description": "Response field with linter comment." + } + } +} diff --git a/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_proto/Message.json b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_proto/Message.json new file mode 100644 index 00000000..92d2cb13 --- /dev/null +++ b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_proto/Message.json @@ -0,0 +1,24 @@ +{ + "title": "Message", + "$id": "http://example.com/schemas/Message.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "Message demonstrates linter comment filtering in descriptions", + "properties": { + "field_with_single_line_comment": { + "title": "field_with_single_line_comment", + "type": "string", + "description": "This field has a single-line linter comment that should be filtered out. This comment should remain visible." + }, + "field_with_multiline_comment": { + "title": "field_with_multiline_comment", + "type": "string", + "description": "This field has a multi-line linter comment that should be filtered out. This comment should remain visible." + }, + "normal_field": { + "title": "normal_field", + "type": "string", + "description": "Normal field without any linter comments. This entire comment should remain visible." + } + } +} diff --git a/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_proto/Response.json b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_proto/Response.json new file mode 100644 index 00000000..7950e1e3 --- /dev/null +++ b/cmd/protoc-gen-jsonschema/examples/tests/lintercomments/schemas_proto/Response.json @@ -0,0 +1,14 @@ +{ + "title": "Response", + "$id": "http://example.com/schemas/Response.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "Response message", + "properties": { + "result": { + "title": "result", + "type": "string", + "description": "Response field with linter comment." + } + } +} diff --git a/cmd/protoc-gen-jsonschema/generator/json-schema.go b/cmd/protoc-gen-jsonschema/generator/json-schema.go index d1f8c9ac..16bb6e24 100644 --- a/cmd/protoc-gen-jsonschema/generator/json-schema.go +++ b/cmd/protoc-gen-jsonschema/generator/json-schema.go @@ -74,7 +74,7 @@ func NewJSONSchemaGenerator(plugin *protogen.Plugin, conf Configuration) *JSONSc conf: conf, plugin: plugin, - linterRulePattern: regexp.MustCompile(`\(-- .* --\)`), + linterRulePattern: regexp.MustCompile(`(?s)\(-- .*? --\)`), } } diff --git a/cmd/protoc-gen-openapi/examples/tests/lintercomments/message.proto b/cmd/protoc-gen-openapi/examples/tests/lintercomments/message.proto new file mode 100644 index 00000000..c6c02d7e --- /dev/null +++ b/cmd/protoc-gen-openapi/examples/tests/lintercomments/message.proto @@ -0,0 +1,59 @@ +// Copyright 2025 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 +// +// http://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. +// + +syntax = "proto3"; + +package tests.lintercomments.message.v1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/google/gnostic/apps/protoc-gen-openapi/examples/tests/lintercomments/message/v1;message"; + +// Test service for linter comment filtering +service TestService { + // TestMethod demonstrates single-line linter comment filtering + rpc TestMethod(TestRequest) returns (TestResponse) { + option (google.api.http) = { + get: "/v1/test" + }; + } +} + +// TestRequest message with various linter comment scenarios +message TestRequest { + // (-- api-linter: core::0140::lower-snake=disabled --) + // This field has a single-line linter comment that should be filtered out. + // This comment should remain visible. + string field_with_single_line_comment = 1; + + // (-- api-linter: core::0133::request-unknown-fields=disabled + // aip.dev/not-precedent: This field is needed to deduplicate asset + // registration. --) + // This field has a multi-line linter comment that should be filtered out. + // This comment should remain visible. + string field_with_multiline_comment = 2; + + // Normal field without any linter comments. + // This entire comment should remain visible. + string normal_field = 3; +} + +// TestResponse message +message TestResponse { + // (-- api-linter: core::0158::response-next-page-token-field=disabled + // aip.dev/not-precedent: We have a different pagination scheme. --) + // Response field with linter comment. + string result = 1; +} diff --git a/cmd/protoc-gen-openapi/examples/tests/lintercomments/openapi.yaml b/cmd/protoc-gen-openapi/examples/tests/lintercomments/openapi.yaml new file mode 100644 index 00000000..64cffd69 --- /dev/null +++ b/cmd/protoc-gen-openapi/examples/tests/lintercomments/openapi.yaml @@ -0,0 +1,85 @@ +# Generated with protoc-gen-openapi +# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi + +openapi: 3.0.3 +info: + title: TestService API + description: Test service for linter comment filtering + version: 0.0.1 +paths: + /v1/test: + get: + tags: + - TestService + description: TestMethod demonstrates single-line linter comment filtering + operationId: TestService_TestMethod + parameters: + - name: field_with_single_line_comment + in: query + description: |- + This field has a single-line linter comment that should be filtered out. + This comment should remain visible. + schema: + type: string + - name: field_with_multiline_comment + in: query + description: |- + This field has a multi-line linter comment that should be filtered out. + This comment should remain visible. + schema: + type: string + - name: normal_field + in: query + description: |- + Normal field without any linter comments. + This entire comment should remain visible. + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TestResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' +components: + schemas: + GoogleProtobufAny: + type: object + properties: + '@type': + type: string + description: The type of the serialized message. + additionalProperties: true + description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. + Status: + type: object + properties: + code: + type: integer + description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + format: int32 + message: + type: string + description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + details: + type: array + items: + $ref: '#/components/schemas/GoogleProtobufAny' + description: A list of messages that carry the error details. There is a common set of message types for APIs to use. + description: 'The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).' + TestResponse: + type: object + properties: + result: + type: string + description: Response field with linter comment. + description: TestResponse message +tags: + - name: TestService diff --git a/cmd/protoc-gen-openapi/generator/generator.go b/cmd/protoc-gen-openapi/generator/generator.go index e548ab21..6c41c393 100644 --- a/cmd/protoc-gen-openapi/generator/generator.go +++ b/cmd/protoc-gen-openapi/generator/generator.go @@ -78,7 +78,7 @@ func NewOpenAPIv3Generator(plugin *protogen.Plugin, conf Configuration, inputFil inputFiles: inputFiles, reflect: NewOpenAPIv3Reflector(conf), generatedSchemas: make([]string, 0), - linterRulePattern: regexp.MustCompile(`\(-- .* --\)`), + linterRulePattern: regexp.MustCompile(`(?s)\(-- .*? --\)`), pathPattern: regexp.MustCompile("{([^=}]+)}"), namedPathPattern: regexp.MustCompile("{(.+)=(.+)}"), } diff --git a/cmd/protoc-gen-openapi/plugin_test.go b/cmd/protoc-gen-openapi/plugin_test.go index 767e9742..e6b12b0d 100644 --- a/cmd/protoc-gen-openapi/plugin_test.go +++ b/cmd/protoc-gen-openapi/plugin_test.go @@ -43,6 +43,7 @@ var openapiTests = []struct { {name: "OpenAPIv3 Annotations", path: "examples/tests/openapiv3annotations/", protofile: "message.proto"}, {name: "AllOf Wrap Message", path: "examples/tests/allofwrap/", protofile: "message.proto"}, {name: "Additional Bindings", path: "examples/tests/additional_bindings/", protofile: "message.proto"}, + {name: "Linter Comments", path: "examples/tests/lintercomments/", protofile: "message.proto"}, } // Set this to true to generate/overwrite the fixtures. Make sure you set it back