پروتوباف encoding/protobuf
خواندن پروندههای .proto، کدگذاری سیمی Protocol Buffers و ساختن کد سلام از آنها.
واردسازی کدگذاری.پروتوباف
Protocol Buffers قالب دودویی گوگل برای پیامهای ساختارمند است. شکل پیامها در پروندهی .proto تعریف میشود و این بسته آن را میخواند، کد سلام برای پیامها و سرویسها میسازد و ابزار سطح پایین نوشتن و خواندن فیلدها را هم دارد.
هر فیلد در بایتها با یک برچسب (شمارهی فیلد و نوع سیم) و سپس مقدارش میآید. عددها معمولاً varint نوشته میشوند: هر بایت ۷ بیت از عدد را دارد و بیت بالایش میگوید بایت دیگری هم هست.
وقتی با سرویسی حرف میزنید که از پیش همین قالب را به کار میبرد، معمولاً از راه جی آر پی سی، یا وقتی چند زبان یک طرحوارهی مشترک دارند، Protocol Buffers را به کار ببرید. میان برنامههای سلام، یا وقتی پروندهی .protoای در کار نیست، مسجپک طرحواره لازم ندارد و جیسون خوانا میماند.
اشتباههای رایج
- خوانندههای ساختهشده عددهای تکراری فشرده را نمیپذیرند. نویسندههای proto3 مثل
protoc، Go و Java یکrepeated int32را بهطور پیشفرض به شکل یک بلوک طولدار میفرستند.Unmarshalساختهشده برای هر عضو یک برچسب انتظار دارد و نوع سیم را بررسی نمیکند، پس فیلد فشرده یا شکست میخورد یا عددهای نادرست میدهد.Marshalساختهشده شکل فشردهنشده را مینویسد که همهی خوانندهها میپذیرند. فیلدهای فشرده را مثل راهنمای عددهای فشرده با دست بخوانید، یا در طرف دیگر فیلد را[packed = false]کنید. - تولیدکننده فیلدهای پیام، شمارشی و
mapرا کنار میگذارد. عضوهای یکoneofفیلدهای معمولی میشوند، پس چیزی جلوی مقدار گرفتن دو عضو با هم را نمیگیرد. این بخشها را با دست بنویسید. - varintها
u64هستند.خواندن عدد متغیریکطبیعی۶۴برمیگرداند؛ خودتان آن را بهصحیح۶۴یاصحیحتبدیل کنید و فیلدهایsintرا ازکدگشایی زیگزاگ۶۴بگذرانید. okرا یک بار، در پایان، بررسی کنید. هر خواننده وقتی داده تمام شود پرچم مشترکokرا نادرست میکند؛ هیچ چیز برنامه را متوقف نمیکند، پس پیش از به کار بردن نتیجه آن را بیازمایید.
راهنمای زیر کارهایی را که در عمل پیش میآید یکییکی جلو میبرد: نوشتن یک پیام با دست، خواندن دوبارهی آن و رد شدن از فیلدهای ناشناخته، پیامهای تودرتو، عددهای تکراری فشرده، انتخاب میان int64 و sint64، و ساختن کد از پروندهی .proto به جای نوشتن آن. همهی بافرهای بایت اینجا بافر بایت از بستهی فشرده سازی هستند، پس برنامهها هر دو بسته را وارد میکنند.
نوشتن یک پیام با دست
یک پیام چیزی جز فیلدهایش پشت سر هم نیست. برای هر فیلد نوشتن برچسب را با شمارهی فیلد در پروندهی .proto و نوع سیم صدا بزنید و بعد نویسندهی مقدار را: نوشتن عدد متغیر برای عدد صحیح، شمارشی و منطقی، نوشتن رشته طولدار برای رشته و نوشتن بایتهای طولدار برای بایتها و پیامهای تودرتو. برنامهی زیر پیام User { id: 42, name: "سارا", admin: true } را مینویسد و بایتهایش را به شکل شانزدهشانزدهی چاپ میکند.
واردسازی کدگذاری.پروتوباف
واردسازی فشرده سازی
تابع شانزدهشانزدهی(ب: فشرده سازی.بافر بایت): رشته:
رقمها := "0123456789abcdef"
ناپایا خروجی := ""
تکرار فشرده سازی.طول بافر(ب) در ی:
مقدار بایت := فشرده سازی.دریافت بایت(ب، ی)
اگر ی بزرگتر ۰: خروجی = خروجی + " " پایان
خروجی = خروجی + رقمها.زیررشته(مقدار بایت / ۱۶، ۱) + رقمها.زیررشته(مقدار بایت % ۱۶، ۱)
پایان
برگشت خروجی
پایان
تابع ریشه:
ناپایا ب := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(ب، ۱، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(ب، ۴۲ برگردان طبیعی۶۴)
پروتوباف.نوشتن برچسب(ب، ۲، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(ب، "سارا")
پروتوباف.نوشتن برچسب(ب، ۳، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(ب، ۱ برگردان طبیعی۶۴)
سرچاپ "تعداد بایت:"، فشرده سازی.طول بافر(ب)
سرچاپ شانزدهشانزدهی(ب)
فشرده سازی.آزادسازی بافر(ب)
پایانخروجی را جفتجفت بخوانید: 08 یعنی فیلد ۱ با نوع سیم ۰ و 2a همان ۴۲ است؛ 12 فیلد ۲ با نوع سیم ۲ است، 08 طول و پس از آن هشت بایت UTF-8 واژهی «سارا» (هر حرف فارسی دو بایت میگیرد)؛ 18 01 هم فیلد ۳ با مقدار درست است. proto3 فیلدی را که مقدار پیشفرض دارد (صفر، رشتهی خالی، نادرست) نمینویسد، پس فرستنده معمولا پیش از نوشتن برچسب مقدار را بررسی میکند.
خواندن پیام و رد شدن از فیلدهای ناشناخته
کدگشایی یک حلقه است: برچسب را بخوانید، به شمارهی فیلد نگاه کنید، مقدار را با خوانندهی مناسبش بخوانید و تا وقتی خواننده خالی نشده ادامه دهید. از شمارهای که نمیشناسید هم باید گذشت و رد کردن فیلد همین کار را با نوع سیم انجام میدهد. به این ترتیب برنامهی قدیمی پیامهای نسخهی جدیدتری را که فیلد تازه دارد بیدردسر میخواند. همهی خوانندهها یک پرچم سالم مشترک میگیرند، پس یک بررسی پس از حلقه پیامی را که نیمهکاره رسیده پیدا میکند.
واردسازی کدگذاری.پروتوباف
واردسازی فشرده سازی
ساختار کاربر:
همگانی شناسه: صحیح = ۰
همگانی نام: رشته = ""
همگانی مدیر: منطقی = نادرست
پایان
تابع خواندن کاربر(داده: تهی*، اندازه: صحیح، سالم &: منطقی): کاربر:
ناپایا ک := کاربر {}
ناپایا خ := فشرده سازی.خواننده بایت جدید(داده، اندازه)
سالم = درست
تا فشرده سازی.باقیمانده(خ) بزرگتر ۰ و سالم:
ناپایا شماره := ۰
ناپایا سیم := ۰
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
اگر وارونه سالم: برگشت ک پایان
ترابرد شماره:
۱:
ک.شناسه = پروتوباف.خواندن عدد متغیر(خ، سالم) برگردان صحیح
بشکن
پایان
۲:
ک.نام = پروتوباف.خواندن رشته طولدار(خ، سالم)
بشکن
پایان
۳:
ک.مدیر = پروتوباف.خواندن عدد متغیر(خ، سالم) نابرابر (۰ برگردان طبیعی۶۴)
بشکن
پایان
وگرنه:
سرچاپ "رد شدن از فیلد ناشناختهی"، شماره
پروتوباف.رد کردن فیلد(خ، سیم، سالم)
پایان
پایان
پایان
برگشت ک
پایان
تابع ریشه:
ناپایا ب := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(ب، ۱، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(ب، ۴۲ برگردان طبیعی۶۴)
پروتوباف.نوشتن برچسب(ب، ۹، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(ب، "افزوده در نسخه ۲")
پروتوباف.نوشتن برچسب(ب، ۲، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(ب، "سارا")
ناپایا سالم := نادرست
ک := خواندن کاربر(ب.داده، فشرده سازی.طول بافر(ب)، سالم)
سرچاپ سالم، ک.شناسه، ک.نام، ک.مدیر
_ := خواندن کاربر(ب.داده، فشرده سازی.طول بافر(ب) - ۲، سالم)
سرچاپ "پیام بریده:"، سالم
فشرده سازی.آزادسازی بافر(ب)
پایانفراخوانی دوم همان بایتها را بدون دو بایت آخر میخواند: طول رشته قول چهار بایت را داده که وجود ندارد، خواندن رشته طولدار پرچم را نادرست میکند و حلقه میایستد. پیش از اعتماد به ساختاری که پر کردهاید همیشه این پرچم را بررسی کنید.
پیامهای تودرتو و تکراری
فیلدی که نوعش پیام دیگری است به شکل بایت نوشته میشود: پیام درونی را در بافر جداگانهای بنویسید و بعد آن را با نوع سیم نوع سیم طولدار و نوشتن بایتهای طولدار در پیام بیرونی بگذارید. فیلد repeated هم همان برچسب است که برای هر عضو یک بار نوشته میشود. در سمت خواندن، خواندن بافر طولدار بایتهای درونی را در بافر تازهای میدهد که با همان حلقه کدگشایی و بعد آزاد میشود.
واردسازی کدگذاری.پروتوباف
واردسازی فشرده سازی
تابع نوشتن قلم(سفارش &: فشرده سازی.بافر بایت، نام: رشته، تعداد: صحیح):
ناپایا قلم := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(قلم، ۱، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(قلم، نام)
پروتوباف.نوشتن برچسب(قلم، ۲، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(قلم، تعداد برگردان طبیعی۶۴)
پروتوباف.نوشتن برچسب(سفارش، ۲، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن بایتهای طولدار(سفارش، قلم.داده، فشرده سازی.طول بافر(قلم))
فشرده سازی.آزادسازی بافر(قلم)
پایان
تابع نمایش قلم(ب: فشرده سازی.بافر بایت):
ناپایا خ := فشرده سازی.خواننده از بافر(ب)
ناپایا سالم := درست
ناپایا نام := ""
ناپایا تعداد := ۰
تا فشرده سازی.باقیمانده(خ) بزرگتر ۰ و سالم:
ناپایا شماره := ۰
ناپایا سیم := ۰
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
اگر شماره برابر ۱: نام = پروتوباف.خواندن رشته طولدار(خ، سالم)
وگرنه شماره برابر ۲: تعداد = پروتوباف.خواندن عدد متغیر(خ، سالم) برگردان صحیح
وگرنه: پروتوباف.رد کردن فیلد(خ، سیم، سالم) پایان
پایان
سرچاپ " قلم"، نام، "تعداد"، تعداد
پایان
تابع ریشه:
ناپایا سفارش := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(سفارش، ۱، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(سفارش، ۱۰۰۱ برگردان طبیعی۶۴)
نوشتن قلم(سفارش، "خودکار"، ۳)
نوشتن قلم(سفارش، "دفتر"، ۱)
سرچاپ "بایتهای سفارش:"، فشرده سازی.طول بافر(سفارش)
ناپایا خ := فشرده سازی.خواننده از بافر(سفارش)
ناپایا سالم := درست
تا فشرده سازی.باقیمانده(خ) بزرگتر ۰ و سالم:
ناپایا شماره := ۰
ناپایا سیم := ۰
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
اگر شماره برابر ۱:
سرچاپ "سفارش"، پروتوباف.خواندن عدد متغیر(خ، سالم)
وگرنه شماره برابر ۲:
ناپایا زیرپیام := پروتوباف.خواندن بافر طولدار(خ، سالم)
نمایش قلم(زیرپیام)
فشرده سازی.آزادسازی بافر(زیرپیام)
وگرنه:
پروتوباف.رد کردن فیلد(خ، سیم، سالم)
پایان
پایان
فشرده سازی.آزادسازی بافر(سفارش)
پایانعددهای تکراری فشرده
یک فیلد repeated از عددها به دو شکل جابهجا میشود. در شکل فشردهنشده هر عضو برچسب خودش را دارد. در شکل فشرده، که در proto3 پیشفرض است، یک برچسب با نوع سیم WT_LEN میآید و varintها پشت سر هم درون آن قرار میگیرند. خوانندهی درست هر دو را میپذیرد، پس به نوع سیم نگاه کنید: برای WT_LEN بلوک را با خواندن بافر طولدار بگیرید و تا خالی شدنش varint بخوانید.
واردسازی کدگذاری.پروتوباف
واردسازی فشرده سازی
تابع خواندن امتیازها(ب: فشرده سازی.بافر بایت): وکتور<صحیح>:
ناپایا خروجی := وکتور {} برگردان وکتور<صحیح>
ناپایا خ := فشرده سازی.خواننده از بافر(ب)
ناپایا سالم := درست
تا فشرده سازی.باقیمانده(خ) بزرگتر ۰ و سالم:
ناپایا شماره := ۰
ناپایا سیم := ۰
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
اگر شماره برابر ۱ و سیم برابر پروتوباف.نوع سیم طولدار:
ناپایا فشرده := پروتوباف.خواندن بافر طولدار(خ، سالم)
ناپایا خف := فشرده سازی.خواننده از بافر(فشرده)
تا فشرده سازی.باقیمانده(خف) بزرگتر ۰ و سالم:
خروجی.بیفزا(پروتوباف.خواندن عدد متغیر(خف، سالم) برگردان صحیح)
پایان
فشرده سازی.آزادسازی بافر(فشرده)
وگرنه شماره برابر ۱ و سیم برابر پروتوباف.نوع سیم متغیر:
خروجی.بیفزا(پروتوباف.خواندن عدد متغیر(خ، سالم) برگردان صحیح)
وگرنه:
پروتوباف.رد کردن فیلد(خ، سیم، سالم)
پایان
پایان
برگشت خروجی
پایان
تابع ریشه:
امتیازها := [۷، ۱۵۰، ۳]
ناپایا بدنه := فشرده سازی.بافر بایت جدید()
هر ا در امتیازها:
پروتوباف.نوشتن عدد متغیر(بدنه، ا برگردان طبیعی۶۴)
پایان
ناپایا فشرده := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(فشرده، ۱، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن بایتهای طولدار(فشرده، بدنه.داده، فشرده سازی.طول بافر(بدنه))
ناپایا جدا := فشرده سازی.بافر بایت جدید()
هر ا در امتیازها:
پروتوباف.نوشتن برچسب(جدا، ۱، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(جدا، ا برگردان طبیعی۶۴)
پایان
سرچاپ "فشرده:"، فشرده سازی.طول بافر(فشرده)، "بایت ->"، خواندن امتیازها(فشرده)
سرچاپ "جدا: "، فشرده سازی.طول بافر(جدا)، "بایت ->"، خواندن امتیازها(جدا)
فشرده سازی.آزادسازی بافر(جدا)
فشرده سازی.آزادسازی بافر(فشرده)
فشرده سازی.آزادسازی بافر(بدنه)
پایانفشردهسازی برای هر عضو یک بایت برچسب صرفهجویی میکند که در فهرستهای بلندِ عددهای کوچک به چشم میآید. برای فیلدی که از کد ساختهشده با protoc در زبانی دیگر میآید هم باید همین کد را به جای Unmarshal ساختهشده به کار ببرید.
عدد منفی: int64 یا sint64
فیلد سادهی int32 یا int64 عدد منفی را به شکل یک عدد بیعلامت بسیار بزرگ مینویسد که همیشه ده بایت میشود. گونههای sint32 و sint64 اول عدد را با زیگزاگ جابهجا میکنند (۰، -۱، ۱، -۲ میشوند ۰، ۱، ۲، ۳) تا عددهای منفی کوچک، کوچک بمانند. پیش از نوشتن عدد متغیر از کدگذاری زیگزاگ۶۴ و پس از خواندن عدد متغیر از کدگشایی زیگزاگ۶۴ استفاده کنید، و برای فیلدهایی مثل جابهجایی یا تغییر دما که اغلب زیر صفرند در پروندهی .proto گونهی sint64 را بگذارید.
واردسازی کدگذاری.پروتوباف
واردسازی فشرده سازی
تابع اندازه عدد متغیر(عدد: طبیعی۶۴): صحیح:
ناپایا ب := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن عدد متغیر(ب، عدد)
اندازه := فشرده سازی.طول بافر(ب)
فشرده سازی.آزادسازی بافر(ب)
برگشت اندازه
پایان
تابع ریشه:
مقدارها := [۵، -۱، -۶۴، ۳۰۰، -۳۰۰]
هر م در مقدارها:
پهن := م برگردان صحیح۶۴
ساده := اندازه عدد متغیر(پهن برگردان طبیعی۶۴)
زیگزاگ := اندازه عدد متغیر(پروتوباف.کدگذاری زیگزاگ۶۴(پهن))
سرچاپ م، "به شکل int64"، ساده، "بایت و به شکل sint64"، زیگزاگ، "بایت میگیرد"
پایان
سرچاپ "زیگزاگ -۱ برابر"، پروتوباف.کدگذاری زیگزاگ۶۴(-۱ برگردان صحیح۶۴)، "و برگشت آن"، پروتوباف.کدگشایی زیگزاگ۶۴(۱ برگردان طبیعی۶۴)
پایانساختن کد از پروندهی .proto
وقتی پیامها بیش از دو سه تا شدند، نوشتن کد را به بسته بسپارید. تولید کد متن .proto را به یک بستهی سلام تبدیل میکند که برای هر پیام یک ساختار و یک تابع Marshal و Unmarshal دارد؛ تولید با سرویسها برای سرویسها هم کد کارخواه gRPC میسازد (بستهی grpc را ببینید). برنامهی زیر فقط سطرهای تعریف کد ساختهشده را چاپ میکند.
واردسازی کدگذاری.پروتوباف
تابع ریشه:
پروتو := "syntax = \"proto3\";\nmessage Point {\n sint32 x = 1;\n sint32 y = 2;\n string label = 3;\n}\n"
ناپایا سالم := نادرست
کد := پروتوباف.تولید کد(پروتو، سالم)
اگر وارونه سالم:
سرچاپ "پروندهی proto تجزیه نشد"
برگشت ۱
پایان
خطها := کد.بشکاف("\n")
هر خط در خطها:
اگر خط.شروع با("pub ") یا خط.شروع با("package "):
سرچاپ خط
پایان
پایان
برگشت ۰
پایانمتن خروجی را در پروندهای مثل point_pb.salam ذخیره کنید، فراخوانی pb "point_pb.salam" را به برنامه بیفزایید و با pb.MarshalPoint(p) یک بافر بایت بگیرید و با pb.UnmarshalPoint(buf.data, buf.len, ok) آن را دوباره بخوانید. کد ساختهشده انگلیسی است، چون نامها از پروندهی .proto میآیند. تولیدکننده فیلدهای ساده، رشته، بایت و فیلدهای تکراری ساده را پوشش میدهد. فیلدهایی را که نوعشان پیام دیگر یا شمارشی است کنار میگذارد، برای فیلدهای map کدی نمیسازد و عضوهای oneof را فیلد معمولی میکند؛ آن چند فیلد را مثل نمونهی تودرتوی بالا با دست بنویسید یا شمارشی را در پروندهی .proto به شکل int32 نگه دارید. عددهای تکراری فقط به شکل فشردهنشده خوانده میشوند؛ راهنمای عددهای فشرده را ببینید.
کدام تابع برای کدام گونهی فیلد
| گونه در .proto | نوع سیم | نوشتن | خواندن |
|---|---|---|---|
int32 int64 uint32 uint64 bool enum | نوع سیم متغیر | نوشتن عدد متغیر | خواندن عدد متغیر |
sint32 sint64 | نوع سیم متغیر | کدگذاری زیگزاگ۶۴ و سپس نوشتن عدد متغیر | خواندن عدد متغیر و سپس کدگشایی زیگزاگ۶۴ |
fixed32 sfixed32 | نوع سیم ثابت۳۲ | نوشتن ثابت۳۲ | خواندن ثابت۳۲ |
fixed64 sfixed64 | نوع سیم ثابت۶۴ | نوشتن ثابت۶۴ | خواندن ثابت۶۴ |
float | نوع سیم ثابت۳۲ | نوشتن اعشار۳۲ | خواندن اعشار۳۲ |
double | نوع سیم ثابت۶۴ | نوشتن اعشار۶۴ | خواندن اعشار۶۴ |
string | نوع سیم طولدار | نوشتن رشته طولدار | خواندن رشته طولدار |
bytes و پیام تودرتو | نوع سیم طولدار | نوشتن بایتهای طولدار | خواندن بافر طولدار |
گونهها
فیلد پروتو PField
ساختار فیلد پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| نوع | kind | صحیح = 0 | نوع فیلد؛ یکی از ثابتهای نوع فیلد. |
| نام نوع | typeName | رشته = "" | نام گونه برای پیام و شمارشی. تجزیهگر نامها را حل نمیکند، پس شمارشی هم نوع پیام میگیرد. |
| نوع کلید | keyKind | صحیح = 0 | نوع کلید برای map. |
| نوع مقدار نقشه | mapValueKind | صحیح = 0 | نوع مقدار برای map. |
| نام نوع مقدار نقشه | mapValueTypeName | رشته = "" | نام گونهی مقدار map. |
| شماره | number | صحیح = 0 | شمارهی فیلد. |
| تکرارشونده | repeated | منطقی = نادرست | فیلد تکرارشونده است. |
| فشرده | packedOpt | منطقی = درست | عددهای تکراری فشرده نوشته شوند. |
| شماره گروه یکی از | oneofIndex | صحیح = -1 | شمارهی گروه oneof؛ -1 اگر نباشد. |
| منسوخ | is_deprecated | منطقی = نادرست | فیلد منسوخ علامت خورده. |
واردسازی کدگذاری.پروتوباف
تابع ریشه:
منبع := "syntax = \"proto3\";\npackage shop;\n\nenum Status { OPEN = 0; DONE = 1; }\n\nmessage Order {\n int64 id = 1;\n repeated string items = 2;\n map<string, int32> counts = 3;\n Status status = 4;\n oneof pay { string card = 5; bool cash = 6; }\n}\n\nservice Orders {\n rpc Get (Order) returns (Order);\n rpc Watch (Order) returns (stream Order);\n}\n"
ناپایا خوب := نادرست
پ := پروتوباف.تجزیه پرونده(منبع، خوب)
سرچاپ خوب، پ.نام پکیج، پ.پیامها.طول()، پ.شمارشیها.طول()، پ.سرویسها.طول()، پ.پروندههای واردشده.طول()
پیام := پ.پیامها[۰]
سرچاپ پیام.نام، پیام.فیلدها.طول()، پیام.گروههای یکی از[۰].نام، پیام.گروههای یکی از[۰].شماره فیلدها
هر ف در پیام.فیلدها:
سرچاپ ف.شماره، ف.نام، پروتوباف.نام نوع فیلد(ف.نوع)، ف.نام نوع، ف.تکرارشونده، ف.شماره گروه یکی از
پایان
م := پیام.فیلدها[۲]
سرچاپ م.نوع == پروتوباف.نوع فیلد نگاشت، پروتوباف.نام نوع فیلد(م.نوع کلید)، پروتوباف.نام نوع فیلد(م.نوع مقدار نقشه)
ش := پ.شمارشیها[۰]
سرچاپ ش.نام، ش.مقدارها[۱].نام، ش.مقدارها[۱].عدد
س := پ.سرویسها[۰]
سرچاپ س.نام، س.متدها[۱].نام، س.متدها[۱].نوع درخواست، س.متدها[۱].خروجی جریانی، س.متدها[۱].ورودی جریانی
سرچاپ پروتوباف.نوع ساده از نام("sint64") == پروتوباف.نوع فیلد صحیح۶۴ زیگزاگ، پروتوباف.نوع ساده از نام("Order")
ناپایا ن := پروتوباف.نشانه گذاری("message A { int32 x = 1; }"، خوب)
سرچاپ خوب، ن.نشانهها.طول()، ن.نشانهها[۰].متن، ن.نشانهها[۰].نوع == پروتوباف.نشانه شناسه، ن.نشانهها[۲].نوع == پروتوباف.نشانه آکولاد باز
سرچاپ ن.نشانهها[۶].مقدار صحیح، ن.نشانهها[۶].شماره خط
_ := پروتوباف.تجزیه پرونده("message {"، خوب)
سرچاپ خوب
پایانگروه یکی از POneof
ساختار گروه یکی ازoneof: از میان فیلدهایش فقط یکی مقدار دارد.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| شماره فیلدها | fieldIndices | وکتور<صحیح> | شمارهی فیلدهای عضو در پیام. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
مقدار شمارشی پروتو PEnumValue
ساختار مقدار شمارشی پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| عدد | number | صحیح = 0 | عدد. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
شمارشی پروتو PEnum
ساختار شمارشی پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| مقدارها | values | وکتور<مقدار شمارشی پروتو> | مقدارها. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
پیام پروتو PMessage
ساختار پیام پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| فیلدها | fields | وکتور<فیلد پروتو> | فیلدها به ترتیب تعریف. |
| گروههای یکی از | oneofs | وکتور<گروه یکی از> | گروههای oneof. |
| پیامهای درونی | nestedMessages | وکتور<پیام پروتو> | پیامهای درونی. |
| شمارشیهای درونی | nestedEnums | وکتور<شمارشی پروتو> | شمارشیهای درونی. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
متد پروتو PMethod
ساختار متد پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| نوع درخواست | inputType | رشته = "" | گونهی ورودی. |
| نوع پاسخ | outputType | رشته = "" | گونهی خروجی. |
| ورودی جریانی | clientStream | منطقی = نادرست | ورودی جریانی است. |
| خروجی جریانی | serverStream | منطقی = نادرست | خروجی جریانی است. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
سرویس پروتو PService
ساختار سرویس پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| متدها | methods | وکتور<متد پروتو> | متدها. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
پرونده پروتو PFile
ساختار پرونده پروتو.proto خواندهشده.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام پکیج | packageName | رشته = "" | نام بسته. |
| پیامها | messages | وکتور<پیام پروتو> | پیامها. |
| شمارشیها | enums | وکتور<شمارشی پروتو> | شمارشیهای سطح بالا. |
| پروندههای واردشده | imports | وکتور<رشته> | پروندههای واردشده. |
| سرویسها | services | وکتور<سرویس پروتو> | سرویسها. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
جریان نشانه پروتو PTokenStream
ساختار جریان نشانه پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نشانهها | toks | وکتور<نشانه پروتو> | نشانهها. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
نشانه پروتو PToken
ساختار نشانه پروتو| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نوع | kind | صحیح | نوع نشانه. |
| متن | lexeme | رشته = "" | متن نشانه. |
| مقدار صحیح | ival | صحیح۶۴ = 0 | مقدار عدد صحیح. |
| مقدار اعشاری | fval | اعشار۶۴ = 0 | مقدار عدد اعشاری. |
| مقدار رشته | sval | رشته = "" | مقدار رشته. |
| شماره خط | line | صحیح = 0 | شمارهی خط. |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
پایاها و متغیرها
نوع فیلدها FK_…
kind هر فیلد: گونههای سادهی پروتوباف، پیام، شمارشی و نگاشت.| نام | انگلیسی | مقدار |
|---|---|---|
| نوع فیلد اعشار۶۴ | FK_DOUBLE | 1 |
| نوع فیلد اعشار۳۲ | FK_FLOAT | 2 |
| نوع فیلد صحیح۳۲ | FK_INT32 | 3 |
| نوع فیلد صحیح۶۴ | FK_INT64 | 4 |
| نوع فیلد طبیعی۳۲ | FK_UINT32 | 5 |
| نوع فیلد طبیعی۶۴ | FK_UINT64 | 6 |
| نوع فیلد صحیح۳۲ زیگزاگ | FK_SINT32 | 7 |
| نوع فیلد صحیح۶۴ زیگزاگ | FK_SINT64 | 8 |
| نوع فیلد ثابت۳۲ | FK_FIXED32 | 9 |
| نوع فیلد ثابت۶۴ | FK_FIXED64 | 10 |
| نوع فیلد ثابت علامتدار۳۲ | FK_SFIXED32 | 11 |
| نوع فیلد ثابت علامتدار۶۴ | FK_SFIXED64 | 12 |
| نوع فیلد منطقی | FK_BOOL | 13 |
| نوع فیلد رشته | FK_STRING | 14 |
| نوع فیلد بایتها | FK_BYTES | 15 |
| نوع فیلد پیام | FK_MESSAGE | 16 |
| نوع فیلد شمارشی | FK_ENUM | 17 |
| نوع فیلد نگاشت | FK_MAP | 18 |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
نوع سیم WT_…
| نام | انگلیسی | مقدار |
|---|---|---|
| نوع سیم متغیر | WT_VARINT | 0 |
| نوع سیم ثابت۶۴ | WT_FIXED64 | 1 |
| نوع سیم طولدار | WT_LEN | 2 |
| نوع سیم ثابت۳۲ | WT_FIXED32 | 5 |
واردسازی کدگذاری.پروتوباف
واردسازی فشرده سازی
تابع ریشه:
ناپایا ب := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(ب، ۱، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(ب، ۱۵۰ برگردان طبیعی۶۴)
سرچاپ فشرده سازی.بافر به پایه۶۴(ب)، پروتوباف.ساخت برچسب(۱، ۰)، پروتوباف.ساخت برچسب(۲، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن برچسب(ب، ۲، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(ب، "سلام")
پروتوباف.نوشتن برچسب(ب، ۳، پروتوباف.نوع سیم ثابت۳۲)
پروتوباف.نوشتن ثابت۳۲(ب، ۷ برگردان طبیعی۳۲)
پروتوباف.نوشتن برچسب(ب، ۴، پروتوباف.نوع سیم ثابت۶۴)
پروتوباف.نوشتن ثابت۶۴(ب، ۹ برگردان طبیعی۶۴)
پروتوباف.نوشتن اعشار۳۲(ب، ۰.۵)
پروتوباف.نوشتن اعشار۶۴(ب، ۲.۲۵)
پروتوباف.نوشتن بایتهای طولدار(ب، ب.داده، ۲)
ناپایا خ := فشرده سازی.خواننده از بافر(ب)
ناپایا سالم := درست
ناپایا شماره := ۰
ناپایا سیم := ۰
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
سرچاپ شماره، سیم، پروتوباف.خواندن عدد متغیر(خ، سالم)
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
سرچاپ شماره، پروتوباف.خواندن رشته طولدار(خ، سالم)
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
پروتوباف.رد کردن فیلد(خ، سیم، سالم)
پروتوباف.خواندن برچسب(خ، شماره، سیم، سالم)
سرچاپ شماره، پروتوباف.خواندن ثابت۶۴(خ، سالم)
سرچاپ پروتوباف.خواندن اعشار۳۲(خ، سالم)، پروتوباف.خواندن اعشار۶۴(خ، سالم)
ب۲ := پروتوباف.خواندن بافر طولدار(خ، سالم)
سرچاپ فشرده سازی.طول بافر(ب۲)، سالم
_ := پروتوباف.خواندن عدد متغیر(خ، سالم)
سرچاپ سالم
سرچاپ پروتوباف.کدگذاری زیگزاگ۳۲(-۱)، پروتوباف.کدگشایی زیگزاگ۳۲(۳ برگردان طبیعی۳۲)، پروتوباف.کدگذاری زیگزاگ۶۴(-۲)، پروتوباف.کدگشایی زیگزاگ۶۴(۴ برگردان طبیعی۶۴)
ناپایا ب۳ := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن ثابت۳۲(ب۳، ۴۲ برگردان طبیعی۳۲)
ناپایا خ۳ := فشرده سازی.خواننده از بافر(ب۳)
سالم = درست
سرچاپ پروتوباف.خواندن ثابت۳۲(خ۳، سالم)
فشرده سازی.آزادسازی بافر(ب)
فشرده سازی.آزادسازی بافر(ب۳)
پایاننوع نشانهها PTK_…
kind نشانههای نشانه گذاری.| نام | انگلیسی | مقدار |
|---|---|---|
| نشانه اتمام | PTK_EOF | 0 |
| نشانه شناسه | PTK_IDENT | 1 |
| نشانه عدد صحیح | PTK_INT | 2 |
| نشانه عدد اعشاری | PTK_FLOAT | 3 |
| نشانه رشته | PTK_STRING | 4 |
| نشانه نقطهویرگول | PTK_SEMI | 5 |
| نشانه آکولاد باز | PTK_LBRACE | 6 |
| نشانه آکولاد بسته | PTK_RBRACE | 7 |
| نشانه پرانتز باز | PTK_LPAREN | 8 |
| نشانه پرانتز بسته | PTK_RPAREN | 9 |
| نشانه کروشه باز | PTK_LBRACKET | 10 |
| نشانه کروشه بسته | PTK_RBRACKET | 11 |
| نشانه زاویه باز | PTK_LANGLE | 12 |
| نشانه زاویه بسته | PTK_RANGLE | 13 |
| نشانه مساوی | PTK_EQ | 14 |
| نشانه ویرگول | PTK_COMMA | 15 |
| نشانه نقطه | PTK_DOT | 16 |
| نشانه منها | PTK_MINUS | 17 |
| نشانه خطا | PTK_ERROR | 18 |
نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
تابعها
نام نوع فیلد FieldKindName
تابع نام نوع فیلد(k: صحیح): رشتهint64.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
نوع ساده از نام ScalarKindFromName
تابع نوع ساده از نام(name: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
تجزیه پرونده ParseFile
تابع تجزیه پرونده(source: رشته، ok &: منطقی): پرونده پروتو.proto (نحو proto3) را میخواند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
نشانه گذاری Tokenize
تابع نشانه گذاری(source: رشته، ok &: منطقی): جریان نشانه پروتونمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Parse.salam
تولید کد GenerateSingle
تابع تولید کد(protoSource: رشته، ok &: منطقی): رشته.proto کد سلام میسازد: یک ساختار برای هر پیام، با تابعهای سریالسازی. فیلدهای پیام، شمارشی و map کنار گذاشته میشوند و خوانندهی ساختهشده عددهای تکراری را فشردهنشده انتظار دارد.واردسازی کدگذاری.پروتوباف
واردسازی رشته
تابع ریشه:
منبع := "syntax = \"proto3\";\nmessage Ping { string text = 1; }\nservice Echo {\n rpc Say (Ping) returns (Ping);\n rpc Stream (stream Ping) returns (stream Ping);\n}\n"
ناپایا خوب := نادرست
کد := پروتوباف.تولید کد(منبع، خوب)
سرچاپ خوب، رشته.شامل است(کد، "struct Ping")
پ := پروتوباف.تجزیه پرونده(منبع، خوب)
سرچاپ پروتوباف.تعداد سرویسها(پ)، پروتوباف.نام سرویس(پ، ۰)، پروتوباف.تعداد متدهای سرویس(پ، ۰)
سرچاپ پروتوباف.امضای متد(پ، ۰، ۰)
سرچاپ پروتوباف.امضای متد(پ، ۰، ۱)
سرچاپ رشته.شامل است(پروتوباف.تولید سرویسها(پ)، "Echo")
همه := پروتوباف.تولید با سرویسها(منبع، خوب)
سرچاپ خوب، رشته.طول(همه) > رشته.طول(کد)
سرچاپ پروتوباف.خلاصه سرویس(منبع، خوب)
پایانتعداد سرویسها ServiceCount
تابع تعداد سرویسها(f: پرونده پروتو): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
نام سرویس ServiceNameAt
تابع نام سرویس(f: پرونده پروتو، i: صحیح): رشتهi.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
تعداد متدهای سرویس ServiceMethodCount
تابع تعداد متدهای سرویس(f: پرونده پروتو، i: صحیح): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
امضای متد ServiceMethodSignature
تابع امضای متد(f: پرونده پروتو، si: صحیح، mi: صحیح): رشتهSay(Ping) returns (Ping).نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
تولید سرویسها GenerateServices
تابع تولید سرویسها(f: پرونده پروتو): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
تولید با سرویسها GenerateWithServices
تابع تولید با سرویسها(protoSource: رشته، ok &: منطقی): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
خلاصه سرویس ServiceSummary
تابع خلاصه سرویس(protoSource: رشته، ok &: منطقی): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Generate.salam
ساخت برچسب MakeTag
تابع ساخت برچسب(fieldNum: صحیح، wireType: صحیح): طبیعی۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن عدد متغیر WriteVarint
تابع نوشتن عدد متغیر(buf &: compress.ByteBuf، n: طبیعی۶۴)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن عدد متغیر ReadVarint
تابع خواندن عدد متغیر(r &: compress.ByteReader، ok &: منطقی): طبیعی۶۴طبیعی۶۴ میخواند؛ اگر بایتها تمام شوند ok نادرست میشود.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن برچسب WriteTag
تابع نوشتن برچسب(buf &: compress.ByteBuf، fieldNum: صحیح، wireType: صحیح)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن برچسب ReadTag
تابع خواندن برچسب(r &: compress.ByteReader، fieldNum &: صحیح، wireType &: صحیح، ok &: منطقی)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
کدگذاری زیگزاگ۳۲ ZigZagEncode32
تابع کدگذاری زیگزاگ۳۲(n: صحیح۳۲): طبیعی۳۲نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
کدگشایی زیگزاگ۳۲ ZigZagDecode32
تابع کدگشایی زیگزاگ۳۲(n: طبیعی۳۲): صحیح۳۲نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
کدگذاری زیگزاگ۶۴ ZigZagEncode64
تابع کدگذاری زیگزاگ۶۴(n: صحیح۶۴): طبیعی۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
کدگشایی زیگزاگ۶۴ ZigZagDecode64
تابع کدگشایی زیگزاگ۶۴(n: طبیعی۶۴): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن ثابت۳۲ WriteFixed32
تابع نوشتن ثابت۳۲(buf &: compress.ByteBuf، v: طبیعی۳۲)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن ثابت۳۲ ReadFixed32
تابع خواندن ثابت۳۲(r &: compress.ByteReader، ok &: منطقی): طبیعی۳۲نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن ثابت۶۴ WriteFixed64
تابع نوشتن ثابت۶۴(buf &: compress.ByteBuf، v: طبیعی۶۴)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن ثابت۶۴ ReadFixed64
تابع خواندن ثابت۶۴(r &: compress.ByteReader، ok &: منطقی): طبیعی۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن اعشار۳۲ WriteFloat
تابع نوشتن اعشار۳۲(buf &: compress.ByteBuf، v: اعشار۶۴)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن اعشار۳۲ ReadFloat
تابع خواندن اعشار۳۲(r &: compress.ByteReader، ok &: منطقی): اعشار۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن اعشار۶۴ WriteDouble
تابع نوشتن اعشار۶۴(buf &: compress.ByteBuf، v: اعشار۶۴)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن اعشار۶۴ ReadDouble
تابع خواندن اعشار۶۴(r &: compress.ByteReader، ok &: منطقی): اعشار۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن بایتهای طولدار WriteLenPrefixedBytes
تابع نوشتن بایتهای طولدار(buf &: compress.ByteBuf، p: تهی*، n: صحیح)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
نوشتن رشته طولدار WriteLenPrefixedStr
تابع نوشتن رشته طولدار(buf &: compress.ByteBuf، s: رشته)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن بافر طولدار ReadLenPrefixedBuf
تابع خواندن بافر طولدار(r &: compress.ByteReader، ok &: منطقی): compress.ByteBufنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
خواندن رشته طولدار ReadLenPrefixedStr
تابع خواندن رشته طولدار(r &: compress.ByteReader، ok &: منطقی): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam
رد کردن فیلد SkipField
تابع رد کردن فیلد(r &: compress.ByteReader، wireType: صحیح، ok &: منطقی)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-protobuf-Wire.salam