public sealed class ResourceDescriptor : IMessage<ResourceDescriptor>, IEquatable<ResourceDescriptor>, IDeepCloneable<ResourceDescriptor>, IBufferMessage, IMessage
A simple descriptor of a resource type.
ResourceDescriptor annotates a resource message (either by means of a
protobuf annotation or use in the service config), 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}.
// For Kubernetes resources, the format is {api group}/{kind}.
option (google.api.resource) = {
type: "pubsub.googleapis.com/Topic"
pattern: "projects/{project}/topics/{topic}"
};
}
The ResourceDescriptor Yaml config will look like:
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.
The plural name used in the resource name and permission names, such as
'projects' for the resource name of 'projects/{project}' and the permission
name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception
to this is for Nested Collections that have stuttering names, as defined
in AIP-122, where the
collection ID in the resource name pattern does not necessarily directly
match the plural value.
public RepeatedField<ResourceDescriptor.Types.Style> Style { get; }
Style flag(s) for this resource.
These indicate that a resource is expected to conform to a given
style. See the specific style flags for additional information.
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.googleapis.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.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-28 UTC."],[[["\u003cp\u003eThe \u003ccode\u003eResourceDescriptor\u003c/code\u003e class describes a resource type, including its schema, type, and name pattern, which can be found in the latest version 2.15.0.\u003c/p\u003e\n"],["\u003cp\u003eA resource's type is defined in the format \u003ccode\u003e{service}/{kind}\u003c/code\u003e, such as \u003ccode\u003epubsub.googleapis.com/Topic\u003c/code\u003e for Pub/Sub topics, or \u003ccode\u003e{api group}/{kind}\u003c/code\u003e for Kubernetes resources.\u003c/p\u003e\n"],["\u003cp\u003eResources can have multiple patterns, which enables them to exist under different parent resources, as seen in the \u003ccode\u003eLogEntry\u003c/code\u003e example with its patterns under projects, folders, organizations, and billing accounts.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eResourceDescriptor\u003c/code\u003e class includes properties like \u003ccode\u003eType\u003c/code\u003e, \u003ccode\u003ePattern\u003c/code\u003e, \u003ccode\u003eHistory\u003c/code\u003e, \u003ccode\u003ePlural\u003c/code\u003e, and \u003ccode\u003eSingular\u003c/code\u003e to define the characteristics of a resource, along with methods to manipulate the resource.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eResourceDescriptor\u003c/code\u003e class will contain optional properties such as \u003ccode\u003eNameField\u003c/code\u003e, and the class may also implement properties such as \u003ccode\u003eStyle\u003c/code\u003e to give further information about the resource.\u003c/p\u003e\n"]]],[],null,["# Class ResourceDescriptor (2.17.0)\n\nVersion latestkeyboard_arrow_down\n\n- [2.17.0 (latest)](/dotnet/docs/reference/Google.Api.CommonProtos/latest/Google.Api.ResourceDescriptor)\n- [2.15.0](/dotnet/docs/reference/Google.Api.CommonProtos/2.15.0/Google.Api.ResourceDescriptor)\n- [2.10.0](/dotnet/docs/reference/Google.Api.CommonProtos/2.10.0/Google.Api.ResourceDescriptor)\n- [2.2.0](/dotnet/docs/reference/Google.Api.CommonProtos/2.2.0/Google.Api.ResourceDescriptor) \n\n public sealed class ResourceDescriptor : IMessage\u003cResourceDescriptor\u003e, IEquatable\u003cResourceDescriptor\u003e, IDeepCloneable\u003cResourceDescriptor\u003e, IBufferMessage, IMessage\n\nA simple descriptor of a resource type.\n\nResourceDescriptor annotates a resource message (either by means of a\nprotobuf annotation or use in the service config), and associates the\nresource's schema, the resource type, and the pattern of the resource name.\n\nExample: \n\n message Topic {\n // Indicates this message defines a resource schema.\n // Declares the resource type in the format of {service}/{kind}.\n // For Kubernetes resources, the format is {api group}/{kind}.\n option (google.api.resource) = {\n type: \"pubsub.googleapis.com/Topic\"\n pattern: \"projects/{project}/topics/{topic}\"\n };\n }\n\nThe ResourceDescriptor Yaml config will look like: \n\n resources:\n - type: \"pubsub.googleapis.com/Topic\"\n pattern: \"projects/{project}/topics/{topic}\"\n\nSometimes, resources have multiple patterns, typically because they can\nlive under multiple parents.\n\nExample: \n\n message LogEntry {\n option (google.api.resource) = {\n type: \"logging.googleapis.com/LogEntry\"\n pattern: \"projects/{project}/logs/{log}\"\n pattern: \"folders/{folder}/logs/{log}\"\n pattern: \"organizations/{organization}/logs/{log}\"\n pattern: \"billingAccounts/{billing_account}/logs/{log}\"\n };\n }\n\nThe ResourceDescriptor Yaml config will look like: \n\n resources:\n - type: 'logging.googleapis.com/LogEntry'\n pattern: \"projects/{project}/logs/{log}\"\n pattern: \"folders/{folder}/logs/{log}\"\n pattern: \"organizations/{organization}/logs/{log}\"\n pattern: \"billingAccounts/{billing_account}/logs/{log}\"\n\nInheritance\n-----------\n\n[object](https://learn.microsoft.com/dotnet/api/system.object) \\\u003e ResourceDescriptor \n\nImplements\n----------\n\n[IMessage](https://cloud.google.com/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.IMessage-1.html)[ResourceDescriptor](/dotnet/docs/reference/Google.Api.CommonProtos/latest/Google.Api.ResourceDescriptor), [IEquatable](https://learn.microsoft.com/dotnet/api/system.iequatable-1)[ResourceDescriptor](/dotnet/docs/reference/Google.Api.CommonProtos/latest/Google.Api.ResourceDescriptor), [IDeepCloneable](https://cloud.google.com/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.IDeepCloneable-1.html)[ResourceDescriptor](/dotnet/docs/reference/Google.Api.CommonProtos/latest/Google.Api.ResourceDescriptor), [IBufferMessage](https://cloud.google.com/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.IBufferMessage.html), [IMessage](https://cloud.google.com/dotnet/docs/reference/Google.Protobuf/latest/Google.Protobuf.IMessage.html) \n\nInherited Members\n-----------------\n\n[object.Equals(object, object)](https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)) \n[object.GetType()](https://learn.microsoft.com/dotnet/api/system.object.gettype) \n[object.ReferenceEquals(object, object)](https://learn.microsoft.com/dotnet/api/system.object.referenceequals)\n\nNamespace\n---------\n\n[Google.Api](/dotnet/docs/reference/Google.Api.CommonProtos/latest/Google.Api)\n\nAssembly\n--------\n\nGoogle.Api.CommonProtos.dll\n\nConstructors\n------------\n\n### ResourceDescriptor()\n\n public ResourceDescriptor()\n\n### ResourceDescriptor(ResourceDescriptor)\n\n public ResourceDescriptor(ResourceDescriptor other)\n\nFields\n------\n\n### HistoryFieldNumber\n\n public const int HistoryFieldNumber = 4\n\nField number for the \"history\" field.\n\n### NameFieldFieldNumber\n\n public const int NameFieldFieldNumber = 3\n\nField number for the \"name_field\" field.\n\n### PatternFieldNumber\n\n public const int PatternFieldNumber = 2\n\nField number for the \"pattern\" field.\n\n### PluralFieldNumber\n\n public const int PluralFieldNumber = 5\n\nField number for the \"plural\" field.\n\n### SingularFieldNumber\n\n public const int SingularFieldNumber = 6\n\nField number for the \"singular\" field.\n\n### StyleFieldNumber\n\n public const int StyleFieldNumber = 10\n\nField number for the \"style\" field.\n\n### TypeFieldNumber\n\n public const int TypeFieldNumber = 1\n\nField number for the \"type\" field.\n\nProperties\n----------\n\n### Descriptor\n\n public static MessageDescriptor Descriptor { get; }\n\n### History\n\n public ResourceDescriptor.Types.History History { get; set; }\n\nOptional. The historical or future-looking state of the resource pattern.\n\nExample: \n\n // The InspectTemplate message originally only supported resource\n // names with organization, and project was added later.\n message InspectTemplate {\n option (google.api.resource) = {\n type: \"dlp.googleapis.com/InspectTemplate\"\n pattern:\n \"organizations/{organization}/inspectTemplates/{inspect_template}\"\n pattern: \"projects/{project}/inspectTemplates/{inspect_template}\"\n history: ORIGINALLY_SINGLE_PATTERN\n };\n }\n\n### NameField\n\n public string NameField { get; set; }\n\nOptional. The field on the resource that designates the resource name\nfield. If omitted, this is assumed to be \"name\".\n\n### Parser\n\n public static MessageParser\u003cResourceDescriptor\u003e Parser { get; }\n\n### Pattern\n\n public RepeatedField\u003cstring\u003e Pattern { get; }\n\nOptional. The relative resource name pattern associated with this resource\ntype. The DNS prefix of the full resource name shouldn't be specified here.\n\nThe path pattern must follow the syntax, which aligns with HTTP binding\nsyntax: \n\n Template = Segment { \"/\" Segment } ;\n Segment = LITERAL | Variable ;\n Variable = \"{\" LITERAL \"}\" ;\n\nExamples: \n\n - \"projects/{project}/topics/{topic}\"\n - \"projects/{project}/knowledgeBases/{knowledge_base}\"\n\nThe components in braces correspond to the IDs for each resource in the\nhierarchy. It is expected that, if multiple patterns are provided,\nthe same component name (e.g. \"project\") refers to IDs of the same\ntype of resource.\n\n### Plural\n\n public string Plural { get; set; }\n\nThe plural name used in the resource name and permission names, such as\n'projects' for the resource name of 'projects/{project}' and the permission\nname of 'cloudresourcemanager.googleapis.com/projects.get'. One exception\nto this is for Nested Collections that have stuttering names, as defined\nin [AIP-122](https://google.aip.dev/122#nested-collections), where the\ncollection ID in the resource name pattern does not necessarily directly\nmatch the `plural` value.\n\nIt is the same concept of the `plural` field in k8s CRD spec\n\u003chttps://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/\u003e\n\nNote: The plural form is required even for singleton resources. See\n\u003chttps://aip.dev/156\u003e\n\n### Singular\n\n public string Singular { get; set; }\n\nThe same concept of the `singular` field in k8s CRD spec\n\u003chttps://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/\u003e\nSuch as \"project\" for the `resourcemanager.googleapis.com/Project` type.\n\n### Style\n\n public RepeatedField\u003cResourceDescriptor.Types.Style\u003e Style { get; }\n\nStyle flag(s) for this resource.\nThese indicate that a resource is expected to conform to a given\nstyle. See the specific style flags for additional information.\n\n### Type\n\n public string Type { get; set; }\n\nThe resource type. It must be in the format of\n{service_name}/{resource_type_kind}. The `resource_type_kind` must be\nsingular and must not include version numbers.\n\nExample: `storage.googleapis.com/Bucket`\n\nThe value of the resource_type_kind must follow the regular expression\n/\\[A-Za-z\\]\\[a-zA-Z0-9\\]+/. It should start with an upper case character and\nshould use PascalCase (UpperCamelCase). The maximum number of\ncharacters allowed for the `resource_type_kind` is 100.\n\nMethods\n-------\n\n### CalculateSize()\n\n public int CalculateSize()\n\n### Clone()\n\n public ResourceDescriptor Clone()\n\n### Equals(ResourceDescriptor)\n\n public bool Equals(ResourceDescriptor other)\n\n### Equals(object)\n\n public override bool Equals(object other)\n\n**Overrides** \n[object.Equals(object)](https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object))\n\n### GetHashCode()\n\n public override int GetHashCode()\n\n**Overrides** \n[object.GetHashCode()](https://learn.microsoft.com/dotnet/api/system.object.gethashcode)\n\n### MergeFrom(ResourceDescriptor)\n\n public void MergeFrom(ResourceDescriptor other)\n\n### MergeFrom(CodedInputStream)\n\n public void MergeFrom(CodedInputStream input)\n\n### ToString()\n\n public override string ToString()\n\n**Overrides** \n[object.ToString()](https://learn.microsoft.com/dotnet/api/system.object.tostring)\n\n### WriteTo(CodedOutputStream)\n\n public void WriteTo(CodedOutputStream output)"]]