google/protocol-buffers

Protocol Buffers : Language Guide (proto3) - Defining A Message Type

C/H 2018. 8. 23. 08:30

Index

Defining A Message Type 메시지 유형 정의

This guide describes how to use the protocol buffer language to structure your protocol buffer data, including .proto file syntax and how to generate data access classes from your .proto files. It covers the proto3 version of the protocol buffers language: for information on the older proto2 syntax, see the Proto2 Language Guide.
이 가이드에서는 프로토콜 버퍼 언어를 사용하여 .proto 파일 구문을 비롯한 프로토콜 버퍼 데이터를 구성하는 방법과 .proto 파일에서 데이터 액세스 클래스를 생성하는 방법을 설명한다. 프로토콜 버퍼 언어의 proto3 버전을 다룬다. 이전 proto2 구문에 대한 내용은 Proto2 언어 가이드를 참조하세요.

This is a reference guide – for a step by step example that uses many of the features described in this document, see the tutorial for your chosen language (currently proto2 only; more proto3 documentation is coming soon).
참조 가이드입니다. – 이 문서에 설명된 많은 기능을 사용하는 단계별 예는 선택한 언어에 대한 자습서를 참조하세요(현재 proto2만 해당, 곧 더 많은 proto3 설명서 제공).

Defining A Message Type 메시지 유형 정의

First let's look at a very simple example. Let's say you want to define a search request message format, where each search request has a query string, the particular page of results you are interested in, and a number of results per page. Here's the .proto file you use to define the message type.
먼저 아주 간단한 예를 봅자. 각 검색 요청에는 쿼리 문자열, 관심 있는 특정 결과 페이지 및 페이지당 여러 결과가 있는 검색 요청 메시지 형식을 정의한다고 가정한다. 다음은 메시지 유형을 정의하는 데 사용하는 .proto 파일이다.

syntax = "proto3";

message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
}
  • The first line of the file specifies that you're using proto3 syntax: if you don't do this the protocol buffer compiler will assume you are using proto2. This must be the first non-empty, non-comment line of the file.
    파일의 첫번째 행에서 proto3 구문을 사용한다고 지정한다. 이 작업을 수행하지 않으면 프로토콜 버퍼 컴파일러에서 proto2를 사용한다고 가정한다. 이 행은 파일의 첫번째 비어 있지 않고 편집되지 않은 행이어야 한다.
  • The SearchRequest message definition specifies three fields (name/value pairs), one for each piece of data that you want to include in this type of message. Each field has a name and a type.
    SearchRequest 메시지 정의는 이 메시지 유형에 포함할 각 데이터 조각에 대해 하나씩 세 개의 필드(이름/값 쌍)를 지정한다. 각 필드에는 이름과 유형이 있다.

Specifying Field Types 필드 유형 지정

In the above example, all the fields are scalar types: two integers (page_number and result_per_page) and a string (query). However, you can also specify composite types for your fields, including enumerations and other message types.
위의 예제에서 모든 필드는 스칼라 유형이다. 두 개의 정수(page_number 및 result_per_page)와 문자열(쿼리). 그러나 열거형 및 기타 메시지 유형을 포함하여 필드의 복합 유형을 지정할 수도 있다.

Assigning Field Numbers 필드 번호 할당

As you can see, each field in the message definition has a unique number. These field numbers are used to identify your fields in the message binary format, and should not be changed once your message type is in use. Note that field numbers in the range 1 through 15 take one byte to encode, including the field number and the field's type (you can find out more about this in Protocol Buffer Encoding). Field numbers in the range 16 through 2047 take two bytes. So you should reserve the numbers 1 through 15 for very frequently occurring message elements. Remember to leave some room for frequently occurring elements that might be added in the future.
보시다시피 메시지 정의의 각 필드에는 고유한 번호가 있다. 이러한 필드번호는 메시지 이진 형식으로 필드를 식별하는데 사용되며, 메시지 유형을 사용한 후에는 변경할수 없다. 1 ~ 15 범위의 필드 번호는 필드 번호와 필드유형을 포함하여 인코딩하는 데 1바이트가 필요하다(프로토콜 버퍼 인코딩에서 자세한 내용을 확인할 수 있음). 16 ~ 2047 범위의 필드 번호는 2바이트다. 따라서 매우 자주 발생하는 메시지 요소에 대해 1부터 15까지의 숫자를 예약해야 한다. 나중에 추가될 수 있는 자주 발생하는 요소를 위한 공간을 남겨두는 것을 잊지마라.

The smallest field number you can specify is 1, and the largest is 229 - 1, or 536,870,911. You also cannot use the numbers 19000 through 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber), as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto. Similarly, you cannot use any previously reserved field numbers.
지정할 수 있는 가장 작은 필드 번호는 1이고, 가장 큰 필드 번호는 229 - 1 또는 536,870,911다. 또한 숫자 19000 ~ 19999(FieldDescriptor::kFirstReservedNumber)는 프로토콜 버퍼 구현에 예약되어 있으므로 사용할 수 없다. 프로토콜 버퍼 컴파일러는 만약 당신이 당신의 .proto에 이 예약 번호들 중 하나를 사용한다면 불평(에러)할 것이다. 마찬가지로 이전에 예약된 필드 번호는 사용할 수 없다.

Specifying Field Rules 필드 규칙 지정

Message fields can be one of the following:
메시지 필드는 다음 중 하나일 수 있다.

singular: a well-formed message can have zero or one of this field (but not more than one). repeated: this field can be repeated any number of times (including zero) in a well-formed message. The order of the repeated values will be preserved. In proto3, repeated fields of scalar numeric types use packed encoding by default.
단수: 올바른 형식의 메시지는 0 또는 이 필드중 하나를 가질 수 있다(단, 하나 이상). 반복됨: 이 필드는 올바른 형식의 메시지에서 (0 포함) 얼마든지 반복할 수 있다. 반복된 값의 순서는 보존된다. proto3에서 스칼라 숫자 유형의 반복 필드는 기본적으로 패딩 인코딩을 사용한다.

You can find out more about packed encoding in Protocol Buffer Encoding.
프로토콜 버퍼 인코딩에서 패킹된 인코딩에 대해 자세히 알아볼 수 있다.

Adding More Message Types 추가 메시지 유형 추가

Multiple message types can be defined in a single .proto file. This is useful if you are defining multiple related messages – so, for example, if you wanted to define the reply message format that corresponds to your SearchResponse message type, you could add it to the same .proto:
단일 .proto 파일에서 여러 메시지 유형을 정의할 수 있다. 이 기능은 여러 관련 메시지를 정의하는 경우 유용하다. 예를 들어 SearchResponse 메시지 유형에 해당하는 응답 메시지 형식을 정의하려는 경우 동일한 .proto:

message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
}

message SearchResponse {
    ...
}

Adding Comments 주석 추가

To add comments to your .proto files, use C/C++-style // and /* ... */ syntax.
.proto 파일에 주석을 추가하려면 C/C++ 스타일 // 및 /* ... */ 구문을 사용한다.

Reserved Fields 예약된 필드

If you update a message type by entirely removing a field, or commenting it out, future users can reuse the field number when making their own updates to the type. This can cause severe issues if they later load old versions of the same .proto, including data corruption, privacy bugs, and so on. One way to make sure this doesn't happen is to specify that the field numbers (and/or names, which can also cause issues for JSON serialization) of your deleted fields are reserved. The protocol buffer compiler will complain if any future users try to use these field identifiers.
필드를 완전히 제거하거나 주석을 통해 메시지 유형을 업데이트하면 나중에 사용자가 해당 유형을 업데이트할 때 필드 번호를 다시 사용할 수 있다. 이 경우 나중에 데이터 손상, 개인정보 버그등을 포함하여 동일한 .proto의 이전 버전을 로드하는 경우 심각한 문제가 발생할 수 있다. 이렇게 하지 않도록 하는 한 가지 방법은 삭제된 필드의 필드 번호(및/또는 이름)를 예약하도록 지정하는 것입니다. 프로토콜 버퍼 컴파일러는 향후 사용자가 이러한 필드 식별자를 사용하려고 할 경우 불만을 제기할 것이다.

message Foo {
    reserved 2, 15, 9 to 11;
    reserved "foo", "bar";
}

Note that you can't mix field names and field numbers in the same reserved statement.
필드이름과 필드번호를 동일한 예약문에서 함께 사용할 수 없다.

What's Generated From Your .proto? 당신의...프로토에서 생성된 것은?

When you run the protocol buffer compiler on a .proto, the compiler generates the code in your chosen language you'll need to work with the message types you've described in the file, including getting and setting field values, serializing your messages to an output stream, and parsing your messages from an input stream.
.proto에서 프로토콜 버퍼 컴파일러를 실행하면, 컴파일러는 사용자가 선택한 언어로 코드를 생성합니다. 여기서 설명하는 메시지 유형(예: 메시지 가져오기 및 구문 분석), 필드 값 직렬화 등)를 사용하여 작업해야 합니다.

  • For C++, the compiler generates a .h and .cc file from each .proto, with a class for each message type described in your file.
    C++의 경우 컴파일러는 파일에 설명된 각 메시지 유형에 대한 클래스를 사용하여 각 .proto에서 .h 및 .cc 파일을 생성한다.
  • For Java, the compiler generates a .java file with a class for each message type, as well as a special Builder classes for creating message class instances.
    Java의 경우 컴파일러는 메시지 클래스 인스턴스를 생성하기 위한 특수 작성기 클래스와 각 메시지 유형에 대한 클래스가 포함된 .java 파일을 생성한다.
  • Python is a little different – the Python compiler generates a module with a static descriptor of each message type in your .proto, which is then used with a metaclass to create the necessary Python data access class at runtime.
    Python은 약간 다르다. Python 컴파일러는 .proto에 있는 각 메시지 유형의 정적 설명자를 사용하여 모듈을 생성하며, 그런 다음 Metaclass와 함께 사용하여 필요한 Python 데이터 액세스 클래스를 만든다.
  • For Go, the compiler generates a .pb.go file with a type for each message type in your file.
    Go의 경우 컴파일러는 파일의 각 메시지 유형에 대해 .pb.go 파일을 생성한다.
  • For Ruby, the compiler generates a .rb file with a Ruby module containing your message types.
    Ruby의 경우 컴파일러는 사용자의 메시지 유형이 포함된 Ruby 모듈을 사용하여 .rb 파일을 생성한다.
  • For Objective-C, the compiler generates a pbobjc.h and pbobjc.m file from each .proto, with a class for each message type described in your file.
    Objective-C의 경우 컴파일러는 각 .proto에서 pbobjc.h 및 pbobjc.m 파일을 생성하고 파일에 설명된 각 메시지 유형에 대한 클래스를 사용한다.
  • For C#, the compiler generates a .cs file from each .proto, with a class for each message type described in your file.
    C#의 경우 컴파일러는 파일에 설명된 각 메시지 유형에 대한 클래스를 사용하여 각 .proto에서 .cs 파일을 생성한다.

You can find out more about using the APIs for each language by following the tutorial for your chosen language (proto3 versions coming soon). For even more API details, see the relevant API reference (proto3 versions also coming soon).
선택한 언어에 대한 자습서(proto3 버전이 곧 출시됨)에 따라 각 언어에 대한 API 사용에 대해 자세히 알아볼 수 있다. API에 대한 자세한 내용은 관련 API 참조(proto3 버전도 곧 출시 예정)를 참조하라.

반응형