NOTA: Este sitio es obsoleto. El sitio se desactivará después del 31 de enero de 2023, y el tráfico se redireccionará al nuevo sitio disponible en https://protobuf.dev. Mientras tanto, solo se implementarán actualizaciones en protobuf.dev.

Especificación del lenguaje de la versión 3 de los búferes de protocolo

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Esta es una referencia de especificación de idioma para la versión 3 del lenguaje del búfer de protocolo (proto3). La sintaxis se especifica mediante el Formulario de Backus-Naur extendido (EBNF):

|   alternation
()  grouping
[]  option (zero or one time)
{}  repetition (any number of times)

Para obtener más información sobre el uso de proto3, consulta la guía del lenguaje.

Elementos léxicos

Letras y dígitos

letter = "A" … "Z" | "a" … "z"
decimalDigit = "0" … "9"
octalDigit   = "0" … "7"
hexDigit     = "0" … "9" | "A" … "F" | "a" … "f"

Identificadores

ident = letter { letter | decimalDigit | "_" }
fullIdent = ident { "." ident }
messageName = ident
enumName = ident
fieldName = ident
oneofName = ident
mapName = ident
serviceName = ident
rpcName = ident
messageType = [ "." ] { ident "." } messageName
enumType = [ "." ] { ident "." } enumName

Literales de número entero

intLit     = decimalLit | octalLit | hexLit
decimalLit = ( "1" … "9" ) { decimalDigit }
octalLit   = "0" { octalDigit }
hexLit     = "0" ( "x" | "X" ) hexDigit { hexDigit } 

Literales de punto flotante

floatLit = ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
decimals  = decimalDigit { decimalDigit }
exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals 

Booleano

boolLit = "true" | "false" 

Literales de string

strLit = ( "'" { charValue } "'" ) |  ( '"' { charValue } '"' )
charValue = hexEscape | octEscape | charEscape | /[^\0\n\\]/
hexEscape = '\' ( "x" | "X" ) hexDigit hexDigit
octEscape = '\' octalDigit octalDigit octalDigit
charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )

Estado vacío

emptyStatement = ";"

Constante

constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | strLit | boolLit 

Sintaxis

La instrucción de sintaxis se usa para definir la versión de protobuf.

syntax = "syntax" "=" ("'" "proto3" "'" | '"' "proto3" '"') ";"

Ejemplo:

syntax = "proto3";

Declaración de importación

La sentencia import se usa para importar las definiciones de otro .proto.

import = "import" [ "weak" | "public" ] strLit ";" 

Ejemplo:

import public "other.proto";

Paquete

El especificador de paquetes se puede usar para evitar conflictos de nombres entre los tipos de mensajes de protocolo.

package = "package" fullIdent ";"

Ejemplo:

package foo.bar;

Opción

Se pueden usar opciones en archivos proto, mensajes, enumeraciones y servicios. Una opción puede ser una opción definida por protobuf o una opción personalizada. Para obtener más información, consulta Opciones en la guía de idiomas.

option = "option" optionName  "=" constant ";"
optionName = ( ident | "(" fullIdent ")" ) { "." ident }

Ejemplo:

option java_package = "com.example.foo";

Campos

Los campos son los elementos básicos de un mensaje de búfer de protocolo. Los campos pueden ser campos normales, uno de los campos o de mapa. Un campo tiene un tipo y un número de campo.

type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
      | "bool" | "string" | "bytes" | messageType | enumType
fieldNumber = intLit;

Campo normal

Cada campo tiene tipo, nombre y número de campo. Puede tener opciones de campo.

field = [ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
fieldOptions = fieldOption { ","  fieldOption }
fieldOption = optionName "=" constant

Ejemplos:

foo.Bar nested_message = 2;
repeated int32 samples = 4 [packed=true];

Campo único y único

Uno de ellos consiste en uno de los campos y un nombre.

oneof = "oneof" oneofName "{" { option | oneofField | emptyStatement } "}"
oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"

Ejemplo:

oneof foo {
    string name = 4;
    SubMessage sub_message = 9;
}

Campo de mapa

Un campo de mapa tiene un tipo de clave, un tipo de valor, un nombre y un número de campo. El tipo de clave puede ser cualquier tipo integral o de string.

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"

Ejemplo:

map<string, Project> projects = 3;

Reservado

Las declaraciones reservadas declaran un rango de números de campo o nombres de campo que no se pueden usar en este mensaje.

reserved = "reserved" ( ranges | strFieldNames ) ";"
ranges = range { "," range }
range =  intLit [ "to" ( intLit | "max" ) ]
strFieldNames = strFieldName { "," strFieldName }
strFieldName = "'" fieldName "'" | '"' fieldName '"'

Ejemplos:

reserved 2, 15, 9 to 11;
reserved "foo", "bar";

Definiciones de nivel superior

Definición de enumeración

La definición de enumeración consta de un nombre y un cuerpo de enumeración. El cuerpo de la enumeración puede tener opciones, campos de enumeración y declaraciones reservadas. Las definiciones de enumeración deben comenzar con el valor de enumeración cero.

enum = "enum" enumName enumBody
enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
enumValueOption = optionName "=" constant

Ejemplo:

enum EnumAllowingAlias {
  option allow_alias = true;
  EAA_UNSPECIFIED = 0;
  EAA_STARTED = 1;
  EAA_RUNNING = 2 [(custom_option) = "hello world"];
}

Definición de mensaje

Un mensaje consta de un nombre y un cuerpo de mensaje. El cuerpo del mensaje puede tener campos, definiciones de enumeraciones anidadas, definiciones de mensajes anidados, opciones, una de ellas, campos de mapas y declaraciones reservadas.

message = "message" messageName messageBody
messageBody = "{" { field | enum | message | option | oneof | mapField |
reserved | emptyStatement } "}"

Ejemplo:

message Outer {
  option (my_option).a = true;
  message Inner {   // Level 2
    int64 ival = 1;
  }
  map<int32, string> my_map = 2;
}

Definición del servicio

service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
messageType ")" (( "{" {option | emptyStatement } "}" ) | ";")

Ejemplo:

service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

Archivo proto

proto = syntax { import | package | option | topLevelDef | emptyStatement }
topLevelDef = message | enum | service

Un archivo .proto de ejemplo:

syntax = "proto3";
import public "other.proto";
option java_package = "com.example.foo";
enum EnumAllowingAlias {
  option allow_alias = true;
  EAA_UNSPECIFIED = 0;
  EAA_STARTED = 1;
  EAA_RUNNING = 1;
  EAA_FINISHED = 2 [(custom_option) = "hello world"];
}
message Outer {
  option (my_option).a = true;
  message Inner {   // Level 2
    int64 ival = 1;
  }
  repeated Inner inner_message = 2;
  EnumAllowingAlias enum_field = 3;
  map<int32, string> my_map = 4;
}