From dd84495caba3474efd48d0b221f60d29253444ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 05:00:03 +0000 Subject: [PATCH 1/7] Initial plan From b1d83f424aca13c90234f977eca0d8fcebd5963a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 05:06:14 +0000 Subject: [PATCH 2/7] Add aep.api.resource annotation proto file Co-authored-by: toumorokoshi <391240+toumorokoshi@users.noreply.github.com> --- proto/aep-api/aep/api/resource.proto | 126 +++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 proto/aep-api/aep/api/resource.proto diff --git a/proto/aep-api/aep/api/resource.proto b/proto/aep-api/aep/api/resource.proto new file mode 100644 index 0000000..d936854 --- /dev/null +++ b/proto/aep-api/aep/api/resource.proto @@ -0,0 +1,126 @@ +// Copyright 2025 Google LLC +// Copyright 2025 AEP.dev +// +// 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 aep.api; + +import "google/protobuf/descriptor.proto"; + +option cc_enable_arenas = true; +option java_multiple_files = true; +option java_outer_classname = "ResourceProto"; +option java_package = "dev.aep.api"; +option objc_class_prefix = "AEP"; + +extend google.protobuf.MessageOptions { + // An annotation that describes a resource definition, see + // [ResourceDescriptor][]. + ResourceDescriptor resource = 1053; +} + +// A descriptor of a resource type. +// +// ResourceDescriptor annotates a resource message and associates the +// resource's schema, the resource type, and the pattern of the resource name. +// +// Example: +// +// message Topic { +// // Indicates this message defines a resource schema. +// // Declares the resource type in the format of {service}/{kind}. +// option (aep.api.resource) = { +// type: "pubsub.example.com/Topic" +// pattern: "projects/{project}/topics/{topic}" +// singular: "topic" +// plural: "topics" +// }; +// } +// +// Resources can have multiple patterns, typically because they can +// live under multiple parents. +// +// Example: +// +// message LogEntry { +// option (aep.api.resource) = { +// type: "logging.example.com/LogEntry" +// pattern: "projects/{project}/logs/{log}" +// pattern: "folders/{folder}/logs/{log}" +// pattern: "organizations/{organization}/logs/{log}" +// singular: "logEntry" +// plural: "logEntries" +// parents: "projects" +// parents: "folders" +// parents: "organizations" +// }; +// } +message ResourceDescriptor { + // The resource type. It must be in the format of + // {service_name}/{resource_type_kind}. The `resource_type_kind` must be + // singular and must not include version numbers. + // + // Example: `storage.example.com/Bucket` + // + // The value of the resource_type_kind must follow the regular expression + // /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and + // should use PascalCase (UpperCamelCase). The maximum number of + // characters allowed for the `resource_type_kind` is 100. + string type = 1; + + // The relative resource name pattern associated with this resource + // type. The DNS prefix of the full resource name shouldn't be specified here. + // + // The path pattern must follow the syntax, which aligns with HTTP binding + // syntax: + // + // Template = Segment { "/" Segment } ; + // Segment = LITERAL | Variable ; + // Variable = "{" LITERAL "}" ; + // + // Examples: + // + // - "projects/{project}/topics/{topic}" + // - "projects/{project}/knowledgeBases/{knowledge_base}" + // + // The components in braces correspond to the IDs for each resource in the + // hierarchy. It is expected that, if multiple patterns are provided, + // the same component name (e.g. "project") refers to IDs of the same + // type of resource. + repeated string pattern = 2; + + // The singular name of the resource, such as "topic" for a Topic resource. + // This is the same concept as the `singular` field in k8s CRD spec. + // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ + string singular = 3; + + // The plural name used in the resource name, such as + // 'topics' for the resource name of 'projects/{project}/topics/{topic}'. + // This is the same concept as the `plural` field in k8s CRD spec. + // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ + // + // Note: The plural form is required even for singleton resources. + string plural = 4; + + // The parent resource type(s) that this resource can be nested under. + // This field specifies one or more parents of the resource, allowing + // the resource to exist under different parent types. + // + // Example: A resource that can exist under both projects and folders + // would list both "projects" and "folders" as parents. + // + // The values should correspond to the plural form of parent resource types. + repeated string parents = 5; +} From a50dbae67c294235c365e6c399044dd8cec92d7d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 05:08:00 +0000 Subject: [PATCH 3/7] Update extension ID to use registered aep.dev range (1253) Co-authored-by: toumorokoshi <391240+toumorokoshi@users.noreply.github.com> --- proto/aep-api/aep/api/resource.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/aep-api/aep/api/resource.proto b/proto/aep-api/aep/api/resource.proto index d936854..aca8ae7 100644 --- a/proto/aep-api/aep/api/resource.proto +++ b/proto/aep-api/aep/api/resource.proto @@ -28,7 +28,7 @@ option objc_class_prefix = "AEP"; extend google.protobuf.MessageOptions { // An annotation that describes a resource definition, see // [ResourceDescriptor][]. - ResourceDescriptor resource = 1053; + ResourceDescriptor resource = 1253; } // A descriptor of a resource type. From 029c5d12a5b0b558a73ae322f514b90e2e696aec Mon Sep 17 00:00:00 2001 From: Yusuke Tsutsumi Date: Sat, 8 Nov 2025 21:57:35 -0800 Subject: [PATCH 4/7] Apply suggestions from code review --- proto/aep-api/aep/api/resource.proto | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proto/aep-api/aep/api/resource.proto b/proto/aep-api/aep/api/resource.proto index aca8ae7..de5e293 100644 --- a/proto/aep-api/aep/api/resource.proto +++ b/proto/aep-api/aep/api/resource.proto @@ -28,7 +28,7 @@ option objc_class_prefix = "AEP"; extend google.protobuf.MessageOptions { // An annotation that describes a resource definition, see // [ResourceDescriptor][]. - ResourceDescriptor resource = 1253; + ResourceDescriptor resource = 1266; } // A descriptor of a resource type. @@ -56,7 +56,7 @@ extend google.protobuf.MessageOptions { // // message LogEntry { // option (aep.api.resource) = { -// type: "logging.example.com/LogEntry" +// type: "logging.example.com/log-entry" // pattern: "projects/{project}/logs/{log}" // pattern: "folders/{folder}/logs/{log}" // pattern: "organizations/{organization}/logs/{log}" @@ -72,11 +72,11 @@ message ResourceDescriptor { // {service_name}/{resource_type_kind}. The `resource_type_kind` must be // singular and must not include version numbers. // - // Example: `storage.example.com/Bucket` + // Example: `storage.example.com/bucket` // // The value of the resource_type_kind must follow the regular expression // /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and - // should use PascalCase (UpperCamelCase). The maximum number of + // should use kebab-case (lowercase-names-with-dashes). The maximum number of // characters allowed for the `resource_type_kind` is 100. string type = 1; @@ -93,7 +93,7 @@ message ResourceDescriptor { // Examples: // // - "projects/{project}/topics/{topic}" - // - "projects/{project}/knowledgeBases/{knowledge_base}" + // - "projects/{project_id}/knowledge-bases/{knowledge_base_id}" // // The components in braces correspond to the IDs for each resource in the // hierarchy. It is expected that, if multiple patterns are provided, From 8c901e8aa518893b47e1cd19c05ac330a2261e2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 06:00:21 +0000 Subject: [PATCH 5/7] Fix resource type to lowercase and parents to singular form Co-authored-by: toumorokoshi <391240+toumorokoshi@users.noreply.github.com> --- proto/aep-api/aep/api/resource.proto | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proto/aep-api/aep/api/resource.proto b/proto/aep-api/aep/api/resource.proto index de5e293..30f2f54 100644 --- a/proto/aep-api/aep/api/resource.proto +++ b/proto/aep-api/aep/api/resource.proto @@ -42,7 +42,7 @@ extend google.protobuf.MessageOptions { // // Indicates this message defines a resource schema. // // Declares the resource type in the format of {service}/{kind}. // option (aep.api.resource) = { -// type: "pubsub.example.com/Topic" +// type: "pubsub.example.com/topic" // pattern: "projects/{project}/topics/{topic}" // singular: "topic" // plural: "topics" @@ -62,9 +62,9 @@ extend google.protobuf.MessageOptions { // pattern: "organizations/{organization}/logs/{log}" // singular: "logEntry" // plural: "logEntries" -// parents: "projects" -// parents: "folders" -// parents: "organizations" +// parents: "project" +// parents: "folder" +// parents: "organization" // }; // } message ResourceDescriptor { @@ -119,8 +119,8 @@ message ResourceDescriptor { // the resource to exist under different parent types. // // Example: A resource that can exist under both projects and folders - // would list both "projects" and "folders" as parents. + // would list both "project" and "folder" as parents. // - // The values should correspond to the plural form of parent resource types. + // The values should correspond to the singular form of parent resource types. repeated string parents = 5; } From 11e28200aec88080e840563225b8fd1d29c94efe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 06:04:08 +0000 Subject: [PATCH 6/7] Update all pattern examples to use _id suffix and kebab-case Co-authored-by: toumorokoshi <391240+toumorokoshi@users.noreply.github.com> --- proto/aep-api/aep/api/resource.proto | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proto/aep-api/aep/api/resource.proto b/proto/aep-api/aep/api/resource.proto index 30f2f54..1af9454 100644 --- a/proto/aep-api/aep/api/resource.proto +++ b/proto/aep-api/aep/api/resource.proto @@ -43,7 +43,7 @@ extend google.protobuf.MessageOptions { // // Declares the resource type in the format of {service}/{kind}. // option (aep.api.resource) = { // type: "pubsub.example.com/topic" -// pattern: "projects/{project}/topics/{topic}" +// pattern: "projects/{project_id}/topics/{topic_id}" // singular: "topic" // plural: "topics" // }; @@ -57,9 +57,9 @@ extend google.protobuf.MessageOptions { // message LogEntry { // option (aep.api.resource) = { // type: "logging.example.com/log-entry" -// pattern: "projects/{project}/logs/{log}" -// pattern: "folders/{folder}/logs/{log}" -// pattern: "organizations/{organization}/logs/{log}" +// pattern: "projects/{project_id}/log-entries/{log_entry_id}" +// pattern: "folders/{folder_id}/log-entries/{log_entry_id}" +// pattern: "organizations/{organization_id}/log-entries/{log_entry_id}" // singular: "logEntry" // plural: "logEntries" // parents: "project" @@ -92,7 +92,7 @@ message ResourceDescriptor { // // Examples: // - // - "projects/{project}/topics/{topic}" + // - "projects/{project_id}/topics/{topic_id}" // - "projects/{project_id}/knowledge-bases/{knowledge_base_id}" // // The components in braces correspond to the IDs for each resource in the @@ -107,7 +107,7 @@ message ResourceDescriptor { string singular = 3; // The plural name used in the resource name, such as - // 'topics' for the resource name of 'projects/{project}/topics/{topic}'. + // 'topics' for the resource name of 'projects/{project_id}/topics/{topic_id}'. // This is the same concept as the `plural` field in k8s CRD spec. // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ // From ba762c013504daff01c649138d78181aa3612c7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 06:09:12 +0000 Subject: [PATCH 7/7] Rename parents field to parent and update all examples Co-authored-by: toumorokoshi <391240+toumorokoshi@users.noreply.github.com> --- proto/aep-api/aep/api/resource.proto | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/proto/aep-api/aep/api/resource.proto b/proto/aep-api/aep/api/resource.proto index 1af9454..bfeee6d 100644 --- a/proto/aep-api/aep/api/resource.proto +++ b/proto/aep-api/aep/api/resource.proto @@ -46,6 +46,7 @@ extend google.protobuf.MessageOptions { // pattern: "projects/{project_id}/topics/{topic_id}" // singular: "topic" // plural: "topics" +// parent: "project" // }; // } // @@ -62,9 +63,9 @@ extend google.protobuf.MessageOptions { // pattern: "organizations/{organization_id}/log-entries/{log_entry_id}" // singular: "logEntry" // plural: "logEntries" -// parents: "project" -// parents: "folder" -// parents: "organization" +// parent: "project" +// parent: "folder" +// parent: "organization" // }; // } message ResourceDescriptor { @@ -119,8 +120,8 @@ message ResourceDescriptor { // the resource to exist under different parent types. // // Example: A resource that can exist under both projects and folders - // would list both "project" and "folder" as parents. + // would list both "project" and "folder" as parent. // // The values should correspond to the singular form of parent resource types. - repeated string parents = 5; + repeated string parent = 5; }